Console Commands
The Symfony framework provides lots of commands through the bin/console script
(e.g. the well-known bin/console cache:clear command). These commands are
created with the Console component. You can also
use it to create your own commands.
Running Commands
Each Symfony application comes with a large set of commands. You can use
the list command to view all available commands in the application:
Note
list is the default command, so running php bin/console is the same.
If you find the command you need, you can run it with the --help option
to view the command's documentation:
Note
--help is one of the built-in global options from the Console component,
which are available for all commands, including those you can create.
To learn more about them, you can read
this section.
APP_ENV & APP_DEBUG
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. You can also define this env vars when running the
command, for instance:
Console Completion
If you are using the Bash, Zsh or Fish shell, you can install Symfony's completion script to get auto completion when typing commands in the terminal. All commands support name and option completion, and some can even complete values.

First, you have to install the completion script once. Run
bin/console completion --help for the installation instructions for
your shell.
Note
When using Bash, make sure you installed and setup the "bash completion"
package for your OS (typically named bash-completion).
After installing and restarting your terminal, you're all set to use completion (by default, by pressing the Tab key).
Tip
Many PHP tools are built using the Symfony Console component (e.g. Composer, PHPStan and Behat). If they are using version 5.4 or higher, you can also install their completion script to enable console completion:
Creating a Command
Commands are defined in classes and auto-registered using the #[AsCommand]
attribute. For example, you may want a command to create a user:
If you can't use PHP attributes, register the command as a service and
tag it with the console.command tag. If you're using the
default services.yaml configuration,
this is already done for you, thanks to autoconfiguration.
8.1
Registering console commands by overriding the Bundle::registerCommands()
method is deprecated. Use the #[AsCommand] attribute or the
console.command service tag instead.
You can also use #[AsCommand] to add a description, usage examples, and
longer help text for the command:
Additionally, you can extend the Command class to leverage advanced features like lifecycle hooks (e.g. initialize() and and interact()):
Method-based Commands
8.1
Support for method-based console commands was introduced in Symfony 8.1.
Instead of creating one class per command, you can define multiple commands
in the same class by adding the #[AsCommand] attribute to individual
public methods. This is useful to group related commands that share the
same dependencies:
Each annotated method becomes an independent command that can be run, listed and tested separately.
Note
When using the Console component without the service container, you can register method-based commands manually:
Running the Command
After configuring and registering the command, you can run it in the terminal:
As you might expect, this command will do nothing as you didn't write any logic
yet. Add your own logic inside the __invoke() method.
Command Aliases
You can define alternative names (aliases) for a command directly in its name
using a pipe (|) separator. The first name in the list becomes the actual
command name; the others are aliases that can also be used to run the command:
Console Output
The __invoke() method has access to the output stream to write messages to
the console:
Now, try executing the command:
Output Sections
The regular console output can be divided into multiple independent regions called "output sections". Create one or more of these sections when you need to clear and overwrite the output information.
Sections are created with the ConsoleOutput::section() method, which returns an instance of ConsoleSectionOutput:
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 as displaying multiple progress bars which are updated independently and appending rows to tables that have already been rendered.
Warning
Terminals only allow overwriting the visible content, so you must take into account the console height when trying to write/overwrite section contents.
Console Input
Use input options or arguments to pass information to the command:
Now, you can pass the username to the command:
Getting Services from the Service Container
To actually create a new user, the command has to access some
services. Since your command is already registered
as a service, you can use normal dependency injection. Imagine you have a
App\Service\UserManager service that you want to access:
See also
Read Console Argument Value Resolvers for more information about advanced
service injection features (such as #[Autowire], #[Target], and
custom value resolvers).
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 required options/arguments. This method is called before validating the input. Note that it will not be called when the command is run without interaction (e.g. when passing the--no-interactionglobal option flag). __invoke()(or execute()) (required)-
This method is executed after
interact()andinitialize(). It contains the logic you want the command to execute and it must return an integer which will be used as the command exit status.
Testing Commands
In test classes extending KernelTestCase,
Symfony provides the runCommand() method to run console commands and inspect
their results. Some assertions are also provided by the ConsoleCommandAssertionsTrait
to check the command executions status:
8.1
The runCommand() method and the ExecutionResult class were
introduced in Symfony 8.1.
The ExecutionResult object gives access to stdout, stderr and the combined
display separately:
You can also assert multiple expectations at once using assertCommandResultEquals():
If your command requires interactive inputs, pass them as the third argument:
Warning
When testing commands using the CommandTester class, console events are
not dispatched. If you need to test those events, use the
ApplicationTester instead.
Note
When using the Console component in a standalone project (without the
Symfony framework), extend \PHPUnit\Framework\TestCase instead of
KernelTestCase and use
Application instead of the
FrameworkBundle one.
Testing Console Applications
In addition to testing single commands, you can test full console applications with the ApplicationTester class:
Note
Don't forget to call setAutoExit(false) on the application before passing
it to ApplicationTester. Without it, the application calls exit()
after running the command, which would terminate the PHPUnit process.
Legacy Command Tester
Using the runCommand() method from KernelTestCase is the recommended way
of testing commands in Symfony applications. However, you can also use the
CommandTester class directly,
which is useful when testing commands outside the Symfony framework or when
you need lower-level control over the testing setup:
Note
If you are using a single-command application,
call setAutoExit(false) on the application to get the command result in CommandTester.
Warning
When testing InputOption::VALUE_NONE command options, you must pass true
to them:
Note
The CommandTester class does not implement ConsoleOutputInterface,
so methods like section() are not directly accessible. To test them,
use the capture_stderr_separately option of the execute() method:
Getting Terminal Information
When testing your commands, it could be useful to understand how your command reacts on different settings like the width and the height of the terminal, or even the color mode being used. You have access to such information thanks to the Terminal class:
Logging Command Errors
Whenever an exception is thrown while running commands, Symfony adds a log
message for it including the entire failing command. In addition, Symfony
registers an event subscriber to listen to the
ConsoleEvents::TERMINATE event and adds a log
message whenever a command doesn't finish with the 0 exit status.
Using Events And Handling Signals
When a command is running, many events are dispatched, one of them allows you to react to signals, read more in this section.
Profiling Commands
Symfony allows you to profile the execution of any command, including yours. First,
make sure that the debug mode and the profiler
are enabled. Then, add the --profile option when running the command:
Symfony will now collect data about the command execution, which is helpful to debug errors or check other issues. When the command execution is over, the profile is accessible through the web page of the profiler.
Among the collected data, the performance panel displays the duration of each argument value resolver used during the command execution, which helps spot slow resolvers.
8.1
The tracing of console argument value resolvers in the profiler's performance panel was introduced in Symfony 8.1.
Tip
If you run the command in verbose mode (adding the -v option), Symfony
will display in the output a clickable link to the command profile (if your
terminal supports links). If you run it in debug verbosity (-vvv) you'll
also see the time and memory consumed by the command.
Warning
When profiling the messenger:consume command from the Messenger
component, add the --no-reset option to the command or you won't get any
profile. Moreover, consider using the --limit option to only process a few
messages to make the profile more readable in the profiler.
Legacy Syntax to Define Commands
Instead of using invokable commands, you can also define commands by extending the Command class. Both syntaxes are supported, but invokable commands are recommended:
You can optionally define a description, help message and the input options and
arguments by overriding the configure() method:
Tip
Using the #[AsCommand] attribute to define a description instead of
the setDescription() method retrieves the command description without
instantiating its class, which makes the php bin/console list command
run much faster.
The configure() method is called automatically at the end of the command
constructor. If your command defines its own constructor, set the properties
first and then call to the parent constructor, to make those properties
available in the configure() method:
This work, including the code samples, is licensed under a Creative Commons BY-SA 3.0 license.