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

Console Laravel Package

symfony/console

Symfony Console makes it easy to build beautiful, testable PHP command‑line tools. Define commands, arguments and options, add interactive prompts, styled output and progress bars, plus robust input/output handling for CLI apps and scripts.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require symfony/console
    

    For Laravel, this is already included via illuminate/console (which wraps Symfony/Console).

  2. First Command: Create a basic command in app/Console/Commands/ (Laravel convention):

    <?php
    namespace App\Console\Commands;
    
    use Illuminate\Console\Command;
    use Symfony\Component\Console\Input\InputOption;
    
    class ExampleCommand extends Command
    {
        protected $signature = 'example:greet {name?} {--yell}';
        protected $description = 'A simple greeting command';
    
        public function handle()
        {
            $name = $this->argument('name') ?: 'World';
            $output = $name . ($this->option('yell') ? '!!!' : '.');
    
            $this->info($output);
        }
    }
    

    Register it in app/Console/Kernel.php:

    protected $commands = [
        Commands\ExampleCommand::class,
    ];
    
  3. Run It:

    php artisan example:greet John --yell
    

    Output:

    [OK] John!!!
    

Key Starting Points

  • Official Docs: Symfony Console Component
  • Laravel Artisan: Built on Symfony/Console; explore vendor/laravel/framework/src/Illuminate/Console/ for Laravel-specific extensions.
  • First Use Case: Replace a one-off Bash script with a structured command (e.g., php artisan db:backup instead of a cron job calling mysqldump).

Implementation Patterns

Core Workflows

1. Command Structure

  • Signature: Define input arguments/options using $signature (e.g., {name?} for optional args, --yell for flags).
  • Options: Use InputOption for complex options (e.g., --limit=<value>).
    $this->addOption('limit', 'l', InputOption::VALUE_REQUIRED, 'Max items', 100);
    
  • Validation: Leverage Symfony’s validators via $this->validateArguments().

2. Output Handling

  • Verbosity Levels: Use $this->output methods (info(), comment(), error()) with verbosity awareness:
    if ($this->output->isVerbose()) {
        $this->output->writeln('Debug details...');
    }
    
  • Progress Bars: For long-running tasks:
    $progressBar = $this->output->createProgressBar(100);
    for ($i = 0; $i < 100; $i++) {
        $progressBar->advance();
    }
    $progressBar->finish();
    
  • Tables: Display tabular data:
    $rows = [['ID', 'Name'], [1, 'John']];
    $this->output->writeln('<comment>Users:</comment>');
    $this->output->writeln($this->formatTable($rows));
    

3. Interactive Prompts

  • Use Symfony\Component\Console\Style\SymfonyStyle for user interaction:
    $io = new SymfonyStyle($this->input, $this->output);
    $name = $io->ask('What is your name?', 'World');
    $confirm = $io->confirm('Proceed?', false);
    $choice = $io->choice('Pick one', ['A', 'B', 'C'], 'A');
    

4. Testing Commands

  • Unit Test a Command:
    use Symfony\Component\Console\Tester\CommandTester;
    
    public function testExampleCommand()
    {
        $command = new ExampleCommand();
        $commandTester = new CommandTester($command);
        $commandTester->execute(['name' => 'Alice']);
        $this->assertStringContainsString('Alice.', $commandTester->getDisplay());
    }
    
  • Integration Test with ApplicationTester:
    use Symfony\Bundle\FrameworkBundle\Console\Application;
    use Symfony\Component\Console\Tester\ApplicationTester;
    
    public function testArtisanCommand()
    {
        $kernel = bootstrap_app();
        $application = new Application($kernel);
        $tester = new ApplicationTester($application);
        $tester->run(['example:greet', 'Bob']);
        $this->assertSame('Bob.', trim($tester->getDisplay()));
    }
    

5. Event-Driven Commands

  • Dispatch events during command execution:
    event(new CommandStarting($this->getName()));
    // ... command logic ...
    event(new CommandCompleted($this->getName(), true));
    
  • Listen to events in EventServiceProvider:
    protected $listen = [
        'command.starting' => [
            Handlers\LogCommandStart::class,
        ],
    ];
    

6. Subcommands and Namespaces

  • Organize commands hierarchically:
    // app/Console/Commands/UserCommand.php
    protected $signature = 'user:{action}';
    protected $description = 'User management commands';
    
    // app/Console/Commands/User/ListCommand.php
    protected $signature = 'user:list';
    
  • Register in Kernel.php:
    protected $commands = [
        Commands\UserCommand::class,
    ];
    

Laravel-Specific Patterns

  • Artisan Extensions: Override Laravel’s Artisan commands by publishing and extending:
    php artisan vendor:publish --tag=artisan-commands
    
  • Command Bus Integration: Use commands with Laravel’s Bus for decoupled logic:
    $this->dispatch(new ProcessBackupJob($path));
    
  • Scheduling: Schedule commands in app/Console/Kernel.php:
    protected function schedule(Schedule $schedule)
    {
        $schedule->command('example:greet John --yell')
                 ->dailyAt('09:00');
    }
    

Gotchas and Tips

Common Pitfalls

  1. Verbosity Confusion:

    • Issue: Output appears at wrong verbosity levels (e.g., debug logs in production).
    • Fix: Use $this->output->isVerbose() or $this->output->isDebug() to gate output:
      if ($this->output->isVeryVerbose()) {
          $this->output->writeln('Detailed debug info...');
      }
      
    • Laravel Note: Artisan’s default verbosity is OutputInterface::VERBOSITY_NORMAL.
  2. Signal Handling:

    • Issue: Commands hang or crash on Ctrl+C (SIGINT).
    • Fix: Register a signal handler:
      $this->input->getSignalHandler()->attach(
          function () use ($progressBar) {
              $progressBar->finish();
              $this->output->writeln('<error>Cancelled!</error>');
              exit(1);
          },
          SIGINT
      );
      
    • Symfony 8+: Use $this->input->getSignalHandler()->attach(fn() => exit(1), SIGINT);.
  3. Windows Line Endings:

    • Issue: \r\n line endings break progress bars or tables.
    • Fix: Normalize output:
      $this->output->setDecorated(false); // Disable ANSI colors if needed
      
    • Workaround: Use str_replace("\r\n", "\n", $output) for raw strings.
  4. Argument Parsing Quirks:

    • Issue: Arguments with # (e.g., --limit=10#) are treated as null.
    • Fix: Escape # in signatures or use InputOption::VALUE_IS_ARRAY.
  5. Interactive Mode in Tests:

    • Issue: ApplicationTester ignores interactive mode.
    • Fix: Explicitly set it:
      $tester->setInput('test');
      $tester->execute(['command:name'], ['interactive' => false]);
      

Debugging Tips

  • Inspect Input/Output:
    $this->output->writeln('Input: ' . print_r($this->input->getArguments(), true));
    
  • Enable Debug Mode:
    php artisan command:name --verbose
    
  • Log to File:
    $this->output->setVerbosity(self::VERBOSITY_DEBUG);
    $this->output->setDecorated(false);
    file_put_contents('debug.log', $this->output->getContent());
    

Performance Quirks

  • Progress Bar Overhead: Disable for non-interactive modes:
    if (!$this->output->isDecorated()) {
        $this->output->writeln('Skipping progress bar (non-interactive)');
    
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.
davejamesmiller/laravel-breadcrumbs
artisanry/parsedown
christhompsontldr/phpsdk
enqueue/dsn
bunny/bunny
enqueue/test
enqueue/null
enqueue/amqp-tools
milesj/emojibase
bower-asset/punycode
bower-asset/inputmask
bower-asset/jquery
bower-asset/yii2-pjax
laravel/nova
spatie/laravel-mailcoach
spatie/laravel-superseeder
laravel/liferaft
nst/json-test-suite
danielmiessler/sec-lists
jackalope/jackalope-transport