Installation Add the package via Composer:
composer require drjele/symfony-console
Laravel does not natively use Symfony Console, so this package bridges Symfony’s console utilities (like Command, Input, Output, Style) into Laravel’s ecosystem.
First Use Case: Creating a Custom Artisan Command
Extend Laravel’s Artisan::command() with Symfony’s rich console features:
use DrJele\Console\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
Artisan::command('app:greet', function () {
return new class extends Command {
protected function configure(): void
{
$this->setDescription('Greet a user');
}
protected function execute(InputInterface $input, OutputInterface $output): int
{
$output->writeln('<info>Hello, Laravel Developer!</info>');
return Command::SUCCESS;
}
};
});
Run it:
php artisan app:greet
Where to Look First
InputOption, Argument).Leveraging Symfony’s Input/Output
Use Symfony’s InputInterface and OutputInterface for advanced console interactions:
protected function execute(InputInterface $input, OutputInterface $output): int
{
$name = $input->getArgument('name') ?? 'Guest';
$output->writeln(sprintf('<comment>Hi %s!</comment>', $name));
return Command::SUCCESS;
}
Define arguments/options in configure():
protected function configure(): void
{
$this->addArgument('name', InputArgument::OPTIONAL, 'Your name');
$this->addOption('verbose', 'v', InputOption::VALUE_NONE, 'Enable verbose mode');
}
Progress Bars and Spinners
Use Symfony’s ProgressBar or Spinner for visual feedback:
use Symfony\Component\Console\Helper\ProgressBar;
protected function execute(InputInterface $input, OutputInterface $output): int
{
$progress = new ProgressBar($output, 100);
$progress->start();
for ($i = 0; $i < 100; $i++) {
// Simulate work
$progress->advance();
}
$progress->finish();
$output->writeln('');
return Command::SUCCESS;
}
Question Helpers Prompt users for input interactively:
use Symfony\Component\Console\Question\Question;
protected function execute(InputInterface $input, OutputInterface $output): int
{
$helper = $this->getHelper('question');
$question = new Question('Enter your name: ');
$name = $helper->ask($input, $output, $question);
$output->writeln(sprintf('<bold>Hello, %s!</bold>', $name));
return Command::SUCCESS;
}
Integration with Laravel Services Inject Laravel’s container or services into commands:
use Illuminate\Support\Facades\Log;
protected function execute(InputInterface $input, OutputInterface $output): int
{
Log::info('Command executed');
$output->writeln('Logging enabled!');
return Command::SUCCESS;
}
CLI Tools for Developers Build internal tools (e.g., database migrations, queue workers) with rich CLI features like:
Automated Tasks
Schedule commands via Laravel’s schedule():
protected function schedule(Schedule $schedule): void
{
$schedule->command('app:cleanup')->daily();
}
Testing Commands
Test commands using Symfony’s Application or Laravel’s Artisan facade:
public function test_greet_command()
{
$this->artisan('app:greet', ['--name' => 'Test'])
->expectsOutput('Hello, Test!')
->assertExitCode(0);
}
Laravel vs. Symfony Naming
InputOption::VALUE_NONE for flags (e.g., --verbose), while Laravel’s Artisan uses false.configure().Output Buffering
Symfony’s OutputInterface may buffer output. Use $output->flush() if real-time updates are needed:
$output->writeln('Processing...');
$output->flush();
Dependency Injection
Avoid mixing Laravel’s DI ($this->app) with Symfony’s ContainerInterface. Prefer constructor injection:
public function __construct(private UserRepository $users) {}
Exit Codes
Symfony’s Command uses Command::SUCCESS (0), Command::FAILURE (1), etc. Ensure Laravel’s Artisan handles them correctly.
Enable Verbose Mode
Use --verbose or -v to debug input/output:
php artisan app:command -vv
Symfony’s Application
For complex debugging, instantiate Symfony’s Application directly:
$application = new Application();
$application->setAutoExit(false);
$application->run(new MyCommand());
Logging
Use Laravel’s Log facade or Symfony’s ErrorHandler for debugging:
use Symfony\Component\Console\Application;
use Symfony\Component\Console\ErrorHandler;
ErrorHandler::register(new class extends ErrorHandler {
public function handleThrowable(Throwable $error): void
{
Log::error($error);
}
});
Reuse Symfony Components Extract common logic (e.g., input validation) into helper classes:
class InputValidator
{
public static function validateName(string $name): bool
{
return strlen($name) > 0;
}
}
Extend Symfony’s Style
Use Style for pre-built UI elements (tables, lists):
use Symfony\Component\Console\Style\SymfonyStyle;
protected function execute(InputInterface $input, OutputInterface $output): int
{
$style = new SymfonyStyle($input, $output);
$style->table(['Name', 'Email'], [['John', '[email protected]']]);
return Command::SUCCESS;
}
Localization
Support multiple languages with Symfony’s Translator:
use Symfony\Component\Translation\Translator;
$translator = new Translator('en');
$output->writeln($translator->trans('welcome.message'));
Performance
For long-running commands, use Symfony’s Process to offload tasks:
use Symfony\Component\Process\Process;
$process = new Process(['php', 'artisan', 'queue:work']);
$process->start();
Documentation
Add --help support automatically via configure():
protected function configure(): void
{
$this->setHelp('This command greets the user.');
}
How can I help you explore Laravel packages today?