Console Commands
Warning: You are browsing the documentation for Symfony 2.x, which is no longer maintained.
Read the updated version of this page for Symfony 7.2 (the current stable version).
The Symfony framework provides lots of commands through the app/console
script
(e.g. the well-known app/console cache:clear
command). These commands are
created with the Console component. You can also
use it to create your own commands.
Creating a Command
Commands are defined in classes which must be created in the Command
namespace
of your bundle (e.g. AppBundle\Command
) and their names must end with the
Command
suffix.
For example, a command called CreateUser
must follow this structure:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
// src/AppBundle/Command/CreateUserCommand.php
namespace AppBundle\Command;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
class CreateUserCommand extends Command
{
protected function configure()
{
// ...
}
protected function execute(InputInterface $input, OutputInterface $output)
{
// ...
}
}
Configuring the Command
First of all, you must configure the name of the command in the configure()
method. Then you can optionally define a help message and the
input options and arguments:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
// ...
protected function configure()
{
$this
// the name of the command (the part after "app/console")
->setName('app:create-user')
// the short description shown while running "php app/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...')
;
}
Registering the Command
Symfony commands must be registered before using them. In order to be registered automatically, a command must be:
- Stored in a directory called
Command/
; - Defined in a class whose name ends with
Command
; - Defined in a class that extends from Command.
If you can't meet these conditions for a command, the alternative is to manually register the command as a service.
Executing the Command
After configuring and registering the command, you can execute it in the terminal:
1
$ php app/console app:create-user
As you might expect, this command will do nothing as you didn't write any logic
yet. Add your own logic inside the execute()
method, which has access to the
input stream (e.g. options and arguments) and the output stream (to write
messages to the console):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
// ...
protected function execute(InputInterface $input, OutputInterface $output)
{
// outputs multiple lines to the console (adding "\n" at the end of each line)
$output->writeln([
'User Creator',
'============',
'',
]);
// 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:
1 2 3 4 5 6
$ php app/console app:create-user
User Creator
============
Whoa!
You are about to create a user.
Console Input
Use input options or arguments to pass information to the command:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
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:
1 2 3 4 5
$ php app/console app:create-user Wouter
User Creator
============
Username: Wouter
See also
Read Console Input (Arguments & Options) for more information about console options and arguments.
Getting Services from the Service Container
To actually create a new user, the command has to access some services. This can be done by making the command extend the ContainerAwareCommand instead:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
// ...
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
class CreateUserCommand extends ContainerAwareCommand
{
// ...
protected function execute(InputInterface $input, OutputInterface $output)
{
// ...
// access the container using getContainer()
$userManager = $this->getContainer()->get('app.user_manager');
$userManager->create($input->getArgument('username'));
$output->writeln('User successfully generated!');
}
}
Now, once you have created the required services and logic, the command will execute
the create()
method of the app.user_manager
service and the user will
be created.
Command Lifecycle
Commands have three lifecycle methods that are invoked when running the command:
- initialize() (optional)
-
This method is executed before the
interact()
and theexecute()
methods. Its main purpose is to initialize variables used in the rest of the command methods. - interact() (optional)
-
This method is executed after
initialize()
and beforeexecute()
. Its purpose is to check if some of the options/arguments are missing and interactively ask the user for those values. This is the last place where 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 most useful one is the CommandTester class. It uses special input and output classes to ease testing without a real console:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
// tests/AppBundle/Command/CreateUserCommandTest.php
namespace Tests\AppBundle\Command;
use AppBundle\Command\CreateUserCommand;
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()
{
self::bootKernel();
$application = new Application(self::$kernel);
$application->add(new CreateUserCommand());
$command = $application->find('app:create-user');
$commandTester = new CommandTester($command);
$commandTester->execute(array(
'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 ApplicationTester.
Note
When using the Console component in a standalone project, use
Symfony\\Component\\Console\\Application
and extend the normal \PHPUnit\Framework\TestCase
.
To be able to use the fully set up service container for your console tests you can extend your test from KernelTestCase:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
// ...
use Symfony\Component\Console\Tester\CommandTester;
use Symfony\Bundle\FrameworkBundle\Console\Application;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
class CreateUserCommandTest extends KernelTestCase
{
public function testExecute()
{
$kernel = static::createKernel();
$kernel->boot();
$application = new Application($kernel);
$application->add(new CreateUserCommand());
$command = $application->find('app:create-user');
$commandTester = new CommandTester($command);
$commandTester->execute(array(
'command' => $command->getName(),
'username' => 'Wouter',
));
$output = $commandTester->getDisplay();
$this->assertContains('Username: Wouter', $output);
// ...
}
}
Learn More
- How to Call Other Commands
- How to Color and Style the Console Output
- How to Call a Command from a Controller
- How to Define Commands as Services
- Console Input (Arguments & Options)
- How to Enable Logging in Console Commands
- How to Generate URLs from the Console
- How to Style a Console Command
- How to Use the Console
- Verbosity Levels
The console component also contains a set of "helpers" - different small tools capable of helping you with different tasks:
- Question Helper: interactively ask the user for information
- Formatter Helper: customize the output colorization
- Progress Bar: shows a progress bar
- Table: displays tabular data as a table