Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laminas Cli Laravel Package

laminas/laminas-cli

Console tooling for Laminas applications and components. Provides a CLI entry point, command discovery/registration, and integration helpers to build and run project-specific commands via Composer and your framework configuration.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require laminas/laminas-cli
    

    This adds the vendor/bin/laminas CLI script to your project.

  2. First Use Case: Run a built-in command (e.g., list to see available commands):

    vendor/bin/laminas list
    

    Outputs registered commands (initially empty unless configured).

  3. Where to Look First:

    • Documentation: Laminas CLI Docs (focus on "Custom Commands" and "Configuration").
    • Source: src/Command/Runner.php (core logic).
    • Config Example: config/autoload/laminas-cli.global.php (if it exists).

Implementation Patterns

1. Basic Command Integration

Workflow:

  1. Create a Symfony Console command (e.g., app/src/Command/MyCommand.php):

    namespace App\Command;
    
    use Symfony\Component\Console\Command\Command;
    use Symfony\Component\Console\Input\InputInterface;
    use Symfony\Component\Console\Output\OutputInterface;
    
    class MyCommand extends Command
    {
        protected function configure(): void
        {
            $this->setName('app:my-command');
        }
    
        protected function execute(InputInterface $input, OutputInterface $output): int
        {
            $output->writeln('Hello from MyCommand!');
            return Command::SUCCESS;
        }
    }
    
  2. Register the Command:

    • Laminas MVC: Add to config/autoload/laminas-cli.global.php:
      return [
          'laminas-cli' => [
              'commands' => [
                  'app:my-command' => App\Command\MyCommand::class,
              ],
          ],
          'service_manager' => [
              'factories' => [
                  App\Command\MyCommand::class => App\Command\MyCommandFactory::class,
              ],
          ],
      ];
      
    • Mezzio: Use dependencies array instead of service_manager.
  3. Run the Command:

    vendor/bin/laminas app:my-command
    

2. Dependency Injection (DI) for Commands

Pattern: Use factories to inject dependencies (e.g., services, repositories) into commands.

Example Factory (app/src/Command/MyCommandFactory.php):

namespace App\Command;

use Interop\Container\ContainerInterface;
use Laminas\ServiceManager\Factory\FactoryInterface;

class MyCommandFactory implements FactoryInterface
{
    public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
    {
        return new MyCommand(
            $container->get(MyService::class)
        );
    }
}

Command Update:

class MyCommand extends Command
{
    private MyService $myService;

    public function __construct(MyService $myService)
    {
        parent::__construct();
        $this->myService = $myService;
    }

    // ... rest of the command
}

3. Attribute-Based Commands (Symfony 6+)

Pattern: Leverage Symfony’s attribute syntax for cleaner command definitions (supported since 1.15.0).

Example:

use Symfony\Component\Console\Attribute\AsCommand;

#[AsCommand(name: 'app:attribute-command')]
class AttributeCommand extends Command
{
    protected function execute(InputInterface $input, OutputInterface $output): int
    {
        $output->writeln('Attribute-based command!');
        return Command::SUCCESS;
    }
}

Registration: No factory needed; register directly in laminas-cli config:

'laminas-cli' => [
    'commands' => [
        'app:attribute-command' => App\Command\AttributeCommand::class,
    ],
],

4. Custom Container Configuration

Pattern: Use the --container flag to specify a custom PSR-11 container (e.g., for testing or modular apps).

Example:

vendor/bin/laminas --container=config/container.test.php app:my-command

Container File (config/container.test.php):

use Psr\Container\ContainerInterface;
use Laminas\ServiceManager\ServiceManager;

return new ServiceManager([
    'factories' => [
        MyService::class => MyServiceFactory::class,
    ],
]);

5. Integration with Laravel

Pattern: While laminas-cli is Laminas-focused, you can adapt it for Laravel by:

  1. Creating a Laravel Service Provider:
    namespace App\Providers;
    
    use Illuminate\Support\ServiceProvider;
    use Symfony\Component\Console\Application;
    
    class LaminasCliServiceProvider extends ServiceProvider
    {
        public function register()
        {
            $this->app->singleton('laminas.cli', function ($app) {
                return new Application();
            });
        }
    }
    
  2. Registering Commands:
    $this->app->extend('laminas.cli', function ($cli) {
        $cli->add(new MyCommand());
        return $cli;
    });
    
  3. Adding a Laravel Artisan Command:
    php artisan laminas:run app:my-command
    
    (Note: Requires custom Artisan command wrapper.)

Gotchas and Tips

1. Common Pitfalls

Issue Solution
Command not found Ensure the command is registered in laminas-cli.commands config.
Dependency injection fails Verify the factory is correctly mapped in service_manager/dependencies.
Container not loaded Use --container flag or ensure the default container is configured.
Symfony Console version mismatch Update laminas-cli to >=1.15.0 for Symfony 7+ support.
PHP version errors Use >=1.13.0 for PHP 8.5, >=1.11.0 for PHP 8.4, etc.

2. Debugging Tips

  • Check Registered Commands:

    vendor/bin/laminas list
    

    Lists all available commands (useful for verifying registration).

  • Enable Verbose Output:

    vendor/bin/laminas --verbose app:my-command
    

    Shows DI container resolution steps.

  • Inspect Container: Add a temporary command to dump the container:

    $container = $this->getApplication()->getKernel()->getContainer();
    var_dump($container->get(MyService::class));
    
  • Symfony Debug: Use Symfony’s built-in debug mode:

    vendor/bin/laminas --debug app:my-command
    

3. Configuration Quirks

  • Global vs. Local Config:

    • Global config (laminas-cli.global.php) is loaded by default.
    • Local config (e.g., laminas-cli.local.php) can override settings.
  • Command Namespacing: Prefix commands with a namespace (e.g., package:command) to avoid collisions:

    'laminas-cli' => [
        'commands' => [
            'package:my-command' => App\Command\MyCommand::class,
        ],
    ],
    
  • Attribute Commands: Ensure your PHP version supports attributes (PHP 8.0+). For older versions, use traditional annotations or XML.


4. Extension Points

  • Custom Command Runner: Extend Laminas\Cli\Command\Runner to modify command resolution logic.

  • Event Listeners: Attach listeners to Symfony’s console events (e.g., CommandEvent):

    use Symfony\Component\Console\Event\ConsoleCommandEvent;
    
    $eventDispatcher->addListener(ConsoleCommandEvent::class, function (ConsoleCommandEvent $event) {
        if ($event->getCommand()->getName() === 'app:my-command') {
            // Pre/post-command logic
        }
    });
    
  • PSR-15 Middleware: Integrate middleware for cross-cutting concerns (e.g., logging, auth):

    $container->get('laminas.cli.middleware')->push(
        new MyMiddleware()
    );
    

5. Performance Tips

  • Avoid Over-Registration: Only register commands you need to reduce container overhead.

  • Lazy-Load Factories: Use lazy factories for heavy dependencies:

    'service_manager' => [
        'factories' => [
            HeavyService::class => function (ContainerInterface $container) {
                return new HeavyService(); // Lazy initialization
            },
        ],
    ],
    
  • Cache Container: For frequent CLI usage, cache the container (e.g., with laminas-servicemanager):

    $container = new ServiceManager([
        'cache_config' => 'config/container.cache.php',
    ]);
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle
atriumphp/atrium
sandermuller/package-boost-laravel
sandermuller/boost-skills
redaxo/core
yusufgenc/filament-api-forge
l3aro/rating-star-for-filament
leek/filament-subtenant-scope