Console Commands
Console commands run in the environment defined in the APP_ENV
variable of the .env
file, which is dev
by default. It also reads the APP_DEBUG
value to turn "debug" mode on or off (it defaults to 1
, which is on).
To run the command in another environment or debug mode, edit the value of APP_ENV
and APP_DEBUG
.
Creating a Command
Commands are defined in classes extendingCommand
. For example, you maywant a command to create a user:
Configuring the Command
You can optionally define a description, help message and theinput options and arguments:
- // ...
- protected function configure()
- {
- $this
- // the short description shown while running "php bin/console list"
- ->setDescription('Creates a new user.')
- // the full command description shown when running the command with
- // the "--help" option
- ->setHelp('This command allows you to create a user...')
- ;
- }
The method is called automatically at the end of the commandconstructor. If your command defines its own constructor, set the propertiesfirst and then call to the parent constructor, to make those propertiesavailable in the configure()
method:
- // ...
- use Symfony\Component\Console\Command\Command;
- use Symfony\Component\Console\Input\InputArgument;
- class CreateUserCommand extends Command
- {
- // ...
- public function __construct(bool $requirePassword = false)
- {
- // best practices recommend to call the parent constructor first and
- // then set your own properties. That wouldn't work in this case
- // because configure() needs the properties set in this constructor
- $this->requirePassword = $requirePassword;
- parent::__construct();
- }
- protected function configure()
- {
- $this
- // ...
- ->addArgument('password', $this->requirePassword ? InputArgument::REQUIRED : InputArgument::OPTIONAL, 'User password')
- ;
- }
- }
Registering the Command
Symfony commands must be registered as services and taggedwith the console.command
tag. If you're using the,this is already done for you, thanks to autoconfiguration.
After configuring and registering the command, you can execute it in the terminal:
As you might expect, this command will do nothing as you didn't write any logicyet. Add your own logic inside the execute()
method.
Console Output
- // ...
- {
- // outputs multiple lines to the console (adding "\n" at the end of each line)
- $output->writeln([
- 'User Creator',
- '============',
- '',
- ]);
- // the value returned by someMethod() can be an iterator (https://secure.php.net/iterator)
- // that generates and returns the messages with the 'yield' PHP keyword
- $output->writeln($this->someMethod());
- // outputs a message followed by a "\n"
- $output->writeln('Whoa!');
- // outputs a message without adding a "\n" at the end of the line
- $output->write('You are about to ');
- $output->write('create a user.');
- }
Now, try executing the command:
- $ php bin/console app:create-user
- User Creator
- ============
- Whoa!
- You are about to create a user.
The regular console output can be divided into multiple independent regionscalled "output sections". Create one or more of these sections when you need toclear and overwrite the output information.
Sections are created with thesection()
method,which returns an instance of:
Note
A new line is appended automatically when displaying information in a section.
Output sections let you manipulate the Console output in advanced ways, such asdisplaying multiple progress bars whichare updated independently and that have already been rendered.
Console Input
Use input options or arguments to pass information to the command:
- use Symfony\Component\Console\Input\InputArgument;
- // ...
- protected function configure()
- {
- $this
- // configure an argument
- ->addArgument('username', InputArgument::REQUIRED, 'The username of the user.')
- // ...
- ;
- }
- // ...
- public function execute(InputInterface $input, OutputInterface $output)
- {
- $output->writeln([
- 'User Creator',
- '============',
- '',
- ]);
- // retrieve the argument value using getArgument()
- $output->writeln('Username: '.$input->getArgument('username'));
- }
Now, you can pass the username to the command:
- $ php bin/console app:create-user Wouter
- User Creator
- ============
- Username: Wouter
Read for more information about console options andarguments.
Getting Services from the Service Container
To actually create a new user, the command has to access some. Since your command is already registeredas a service, you can use normal dependency injection. Imagine you have aApp\Service\UserManager
service that you want to access:
Commands have three lifecycle methods that are invoked when running thecommand:
initialize()
(optional)- This method is executed before the
interact()
and the methods. Its main purpose is to initialize variables used in the rest ofthe command methods. (optional)
- This method is executed after
initialize()
and beforeexecute()
.Its purpose is to check if some of the options/arguments are missingand interactively ask the user for those values. This is the last placewhere you can ask for missing options/arguments. After this command,missing options/arguments will result in an error. execute()
(required)- This method is executed after
interact()
andinitialize()
.It contains the logic you want the command to execute.
Testing Commands
Symfony provides several tools to help you test your commands. The mostuseful one is the CommandTester
class. It uses special input and output classes to ease testing without a realconsole:
- // tests/Command/CreateUserCommandTest.php
- namespace App\Tests\Command;
- use Symfony\Bundle\FrameworkBundle\Console\Application;
- use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
- use Symfony\Component\Console\Tester\CommandTester;
- class CreateUserCommandTest extends KernelTestCase
- {
- public function testExecute()
- {
- $kernel = static::createKernel();
- $application = new Application($kernel);
- $command = $application->find('app:create-user');
- $commandTester = new CommandTester($command);
- $commandTester->execute([
- 'command' => $command->getName(),
- // pass arguments to the helper
- 'username' => 'Wouter',
- // prefix the key with two dashes when passing options,
- // e.g: '--some-option' => 'option_value',
- ]);
- // the output of the command in the console
- $output = $commandTester->getDisplay();
- $this->assertContains('Username: Wouter', $output);
- // ...
- }
- }
Tip
You can also test a whole console application by using.
Note
When using the Console component in a standalone project, useSymfony\Component\Console\Application
and extend the normal .
Logging Command Errors
Whenever an exception is thrown while running commands, Symfony adds a logmessage for it including the entire failing command. In addition, Symfonyregisters an event subscriber to listen to the and adds a logmessage whenever a command doesn't finish with the 0
exit status.
Learn More
- How to Color and Style the Console Output
- How to Define Commands as Services
- Console Input (Arguments & Options)
- Prevent Multiple Executions of a Console Command
- Verbosity Levels
The console component also contains a set of "helpers" - different smalltools capable of helping you with different tasks:
- : interactively ask the user for information
- Formatter Helper: customize the output colorization
- : displays tabular data as a table