Symfony
sponsored by SensioLabs
Menu
  • About
  • Documentation
  • Screencasts
  • Cloud
  • Certification
  • Community
  • Businesses
  • News
  • Download
  1. Home
  2. Documentation
  3. Components
  4. Console
  5. The Console Component
  • Documentation
  • Book
  • Reference
  • Bundles
  • Cloud
Search by Algolia

Table of Contents

  • Installation
  • Creating a basic Command
    • Coloring the Output
    • Verbosity Levels
  • Using Command Arguments
  • Using Command Options
  • Console Helpers
  • Testing Commands
  • Calling an Existing Command
  • Learn More!

The Console Component

Edit this page

Warning: You are browsing the documentation for Symfony 2.5, which is no longer maintained.

Read the updated version of this page for Symfony 6.2 (the current stable version).

The Console Component

The Console component eases the creation of beautiful and testable command line interfaces.

The Console component allows you to create command-line commands. Your console commands can be used for any recurring task, such as cronjobs, imports, or other batch jobs.

Installation

You can install the component in 2 different ways:

  • Install it via Composer (symfony/console on Packagist);
  • Use the official Git repository (https://github.com/symfony/Console).

Note

Windows does not support ANSI colors by default so the Console component detects and disables colors where Windows does not have support. However, if Windows is not configured with an ANSI driver and your console commands invoke other scripts which emit ANSI color sequences, they will be shown as raw escape characters.

To enable ANSI color support for Windows, please install ANSICON.

Creating a basic Command

To make a console command that greets you from the command line, create GreetCommand.php and add the following to it:

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
37
38
39
40
41
42
43
44
45
namespace Acme\Console\Command;

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;

class GreetCommand extends Command
{
    protected function configure()
    {
        $this
            ->setName('demo:greet')
            ->setDescription('Greet someone')
            ->addArgument(
                'name',
                InputArgument::OPTIONAL,
                'Who do you want to greet?'
            )
            ->addOption(
               'yell',
               null,
               InputOption::VALUE_NONE,
               'If set, the task will yell in uppercase letters'
            )
        ;
    }

    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $name = $input->getArgument('name');
        if ($name) {
            $text = 'Hello '.$name;
        } else {
            $text = 'Hello';
        }

        if ($input->getOption('yell')) {
            $text = strtoupper($text);
        }

        $output->writeln($text);
    }
}

You also need to create the file to run at the command line which creates an Application and adds commands to it:

1
2
3
4
5
6
7
8
9
10
11
12
#!/usr/bin/env php
<?php
// application.php

require __DIR__.'/vendor/autoload.php';

use Acme\Console\Command\GreetCommand;
use Symfony\Component\Console\Application;

$application = new Application();
$application->add(new GreetCommand);
$application->run();

Test the new console command by running the following

1
$ php application.php demo:greet Fabien

This will print the following to the command line:

1
Hello Fabien

You can also use the --yell option to make everything uppercase:

1
$ php application.php demo:greet Fabien --yell

This prints:

1
HELLO FABIEN

Coloring the Output

Whenever you output text, you can surround the text with tags to color its output. For example:

1
2
3
4
5
6
7
8
9
10
11
// green text
$output->writeln('<info>foo</info>');

// yellow text
$output->writeln('<comment>foo</comment>');

// black text on a cyan background
$output->writeln('<question>foo</question>');

// white text on a red background
$output->writeln('<error>foo</error>');

It is possible to define your own styles using the class OutputFormatterStyle:

1
2
3
4
5
6
use Symfony\Component\Console\Formatter\OutputFormatterStyle;

// ...
$style = new OutputFormatterStyle('red', 'yellow', array('bold', 'blink'));
$output->getFormatter()->setStyle('fire', $style);
$output->writeln('<fire>foo</fire>');

Available foreground and background colors are: black, red, green, yellow, blue, magenta, cyan and white.

And available options are: bold, underscore, blink, reverse and conceal.

You can also set these colors and options inside the tagname:

1
2
3
4
5
6
7
8
// green text
$output->writeln('<fg=green>foo</fg=green>');

// black text on a cyan background
$output->writeln('<fg=black;bg=cyan>foo</fg=black;bg=cyan>');

// bold text on a yellow background
$output->writeln('<bg=yellow;options=bold>foo</bg=yellow;options=bold>');

Verbosity Levels

2.3

The VERBOSITY_VERY_VERBOSE and VERBOSITY_DEBUG constants were introduced in version 2.3

The console has 5 levels of verbosity. These are defined in the OutputInterface:

Mode Value
OutputInterface::VERBOSITY_QUIET Do not output any messages
OutputInterface::VERBOSITY_NORMAL The default verbosity level
OutputInterface::VERBOSITY_VERBOSE Increased verbosity of messages
OutputInterface::VERBOSITY_VERY_VERBOSE Informative non essential messages
OutputInterface::VERBOSITY_DEBUG Debug messages

You can specify the quiet verbosity level with the --quiet or -q option. The --verbose or -v option is used when you want an increased level of verbosity.

Tip

The full exception stacktrace is printed if the VERBOSITY_VERBOSE level or above is used.

It is possible to print a message in a command for only a specific verbosity level. For example:

1
2
3
if (OutputInterface::VERBOSITY_VERBOSE <= $output->getVerbosity()) {
    $output->writeln(...);
}

2.4

The isQuiet(), isVerbose(), isVeryVerbose() and isDebug() methods were introduced in Symfony 2.4

There are also more semantic methods you can use to test for each of the verbosity levels:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
if ($output->isQuiet()) {
    // ...
}

if ($output->isVerbose()) {
    // ...
}

if ($output->isVeryVerbose()) {
    // ...
}

if ($output->isDebug()) {
    // ...
}

When the quiet level is used, all output is suppressed as the default write() method returns without actually printing.

Tip

The MonologBridge provides a ConsoleHandler class that allows you to display messages on the console. This is cleaner than wrapping your output calls in conditions. For an example use in the Symfony Framework, see How to Configure Monolog to Display Console Messages.

Using Command Arguments

The most interesting part of the commands are the arguments and options that you can make available. Arguments are the strings - separated by spaces - that come after the command name itself. They are ordered, and can be optional or required. For example, add an optional last_name argument to the command and make the name argument required:

1
2
3
4
5
6
7
8
9
10
11
12
$this
    // ...
    ->addArgument(
        'name',
        InputArgument::REQUIRED,
        'Who do you want to greet?'
    )
    ->addArgument(
        'last_name',
        InputArgument::OPTIONAL,
        'Your last name?'
    );

You now have access to a last_name argument in your command:

1
2
3
if ($lastName = $input->getArgument('last_name')) {
    $text .= ' '.$lastName;
}

The command can now be used in either of the following ways:

1
2
$ php application.php demo:greet Fabien
$ php application.php demo:greet Fabien Potencier

It is also possible to let an argument take a list of values (imagine you want to greet all your friends). For this it must be specified at the end of the argument list:

1
2
3
4
5
6
7
$this
    // ...
    ->addArgument(
        'names',
        InputArgument::IS_ARRAY,
        'Who do you want to greet (separate multiple names with a space)?'
    );

To use this, just specify as many names as you want:

1
$ php application.php demo:greet Fabien Ryan Bernhard

You can access the names argument as an array:

1
2
3
if ($names = $input->getArgument('names')) {
    $text .= ' '.implode(', ', $names);
}

There are 3 argument variants you can use:

Mode Value
InputArgument::REQUIRED The argument is required
InputArgument::OPTIONAL The argument is optional and therefore can be omitted
InputArgument::IS_ARRAY The argument can contain an indefinite number of arguments and must be used at the end of the argument list

You can combine IS_ARRAY with REQUIRED and OPTIONAL like this:

1
2
3
4
5
6
7
$this
    // ...
    ->addArgument(
        'names',
        InputArgument::IS_ARRAY | InputArgument::REQUIRED,
        'Who do you want to greet (separate multiple names with a space)?'
    );

Using Command Options

Unlike arguments, options are not ordered (meaning you can specify them in any order) and are specified with two dashes (e.g. --yell - you can also declare a one-letter shortcut that you can call with a single dash like -y). Options are always optional, and can be setup to accept a value (e.g. --dir=src) or simply as a boolean flag without a value (e.g. --yell).

Tip

It is also possible to make an option optionally accept a value (so that --yell, --yell=loud or --yell loud work). Options can also be configured to accept an array of values.

For example, add a new option to the command that can be used to specify how many times in a row the message should be printed:

1
2
3
4
5
6
7
8
9
$this
    // ...
    ->addOption(
        'iterations',
        null,
        InputOption::VALUE_REQUIRED,
        'How many times should the message be printed?',
        1
    );

Next, use this in the command to print the message multiple times:

1
2
3
for ($i = 0; $i < $input->getOption('iterations'); $i++) {
    $output->writeln($text);
}

Now, when you run the task, you can optionally specify a --iterations flag:

1
2
$ php application.php demo:greet Fabien
$ php application.php demo:greet Fabien --iterations=5

The first example will only print once, since iterations is empty and defaults to 1 (the last argument of addOption). The second example will print five times.

Recall that options don't care about their order. So, either of the following will work:

1
2
$ php application.php demo:greet Fabien --iterations=5 --yell
$ php application.php demo:greet Fabien --yell --iterations=5

There are 4 option variants you can use:

Option Value
InputOption::VALUE_IS_ARRAY This option accepts multiple values (e.g. --dir=/foo --dir=/bar)
InputOption::VALUE_NONE Do not accept input for this option (e.g. --yell)
InputOption::VALUE_REQUIRED This value is required (e.g. --iterations=5), the option itself is still optional
InputOption::VALUE_OPTIONAL This option may or may not have a value (e.g. --yell or --yell=loud)

You can combine VALUE_IS_ARRAY with VALUE_REQUIRED or VALUE_OPTIONAL like this:

1
2
3
4
5
6
7
8
9
$this
    // ...
    ->addOption(
        'colors',
        null,
        InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY,
        'Which colors do you like?',
        array('blue', 'red')
    );

Console Helpers

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

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
use Acme\Console\Command\GreetCommand;
use Symfony\Component\Console\Application;
use Symfony\Component\Console\Tester\CommandTester;

class ListCommandTest extends \PHPUnit_Framework_TestCase
{
    public function testExecute()
    {
        $application = new Application();
        $application->add(new GreetCommand());

        $command = $application->find('demo:greet');
        $commandTester = new CommandTester($command);
        $commandTester->execute(array('command' => $command->getName()));

        $this->assertRegExp('/.../', $commandTester->getDisplay());

        // ...
    }
}

The getDisplay() method returns what would have been displayed during a normal call from the console.

You can test sending arguments and options to the command by passing them as an array to the execute() method:

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 Acme\Console\Command\GreetCommand;
use Symfony\Component\Console\Application;
use Symfony\Component\Console\Tester\CommandTester;

class ListCommandTest extends \PHPUnit_Framework_TestCase
{
    // ...

    public function testNameIsOutput()
    {
        $application = new Application();
        $application->add(new GreetCommand());

        $command = $application->find('demo:greet');
        $commandTester = new CommandTester($command);
        $commandTester->execute(array(
            'command'      => $command->getName(),
            'name'         => 'Fabien',
            '--iterations' => 5,
        ));

        $this->assertRegExp('/Fabien/', $commandTester->getDisplay());
    }
}

Tip

You can also test a whole console application by using ApplicationTester.

Calling an Existing Command

If a command depends on another one being run before it, instead of asking the user to remember the order of execution, you can call it directly yourself. This is also useful if you want to create a "meta" command that just runs a bunch of other commands (for instance, all commands that need to be run when the project's code has changed on the production servers: clearing the cache, generating Doctrine2 proxies, dumping Assetic assets, ...).

Calling a command from another one is straightforward:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
protected function execute(InputInterface $input, OutputInterface $output)
{
    $command = $this->getApplication()->find('demo:greet');

    $arguments = array(
        'command' => 'demo:greet',
        'name'    => 'Fabien',
        '--yell'  => true,
    );

    $input = new ArrayInput($arguments);
    $returnCode = $command->run($input, $output);

    // ...
}

First, you find() the command you want to execute by passing the command name.

Then, you need to create a new ArrayInput with the arguments and options you want to pass to the command.

Eventually, calling the run() method actually executes the command and returns the returned code from the command (return value from command's execute() method).

Note

Most of the time, calling a command from code that is not executed on the command line is not a good idea for several reasons. First, the command's output is optimized for the console. But more important, you can think of a command as being like a controller; it should use the model to do something and display feedback to the user. So, instead of calling a command from the Web, refactor your code and move the logic to a new class.

Learn More!

  • Using Console Commands, Shortcuts and Built-in Commands
  • Building a single Command Application
  • Changing the Default Command
  • Using Events
  • Understanding how Console Arguments Are Handled
This work, including the code samples, is licensed under a Creative Commons BY-SA 3.0 license.
We stand with Ukraine.
Version:
Symfony Code Performance Profiling

Symfony Code Performance Profiling

Peruse our complete Symfony & PHP solutions catalog for your web development needs.

Peruse our complete Symfony & PHP solutions catalog for your web development needs.

↓ Our footer now uses the colors of the Ukrainian flag because Symfony stands with the people of Ukraine.

Avatar of François Pluchino, a Symfony contributor

Thanks François Pluchino (@francoispluchino) for being a Symfony contributor

9 commits • 244 lines changed

View all contributors that help us make Symfony

Become a Symfony contributor

Be an active part of the community and contribute ideas, code and bug fixes. Both experts and newcomers are welcome.

Learn how to contribute

Symfony™ is a trademark of Symfony SAS. All rights reserved.

  • What is Symfony?
    • Symfony at a Glance
    • Symfony Components
    • Case Studies
    • Symfony Releases
    • Security Policy
    • Logo & Screenshots
    • Trademark & Licenses
    • symfony1 Legacy
  • Learn Symfony
    • Symfony Docs
    • Symfony Book
    • Reference
    • Bundles
    • Best Practices
    • Training
    • eLearning Platform
    • Certification
  • Screencasts
    • Learn Symfony
    • Learn PHP
    • Learn JavaScript
    • Learn Drupal
    • Learn RESTful APIs
  • Community
    • SymfonyConnect
    • Support
    • How to be Involved
    • Code of Conduct
    • Events & Meetups
    • Projects using Symfony
    • Downloads Stats
    • Contributors
    • Backers
  • Blog
    • Events & Meetups
    • A week of symfony
    • Case studies
    • Cloud
    • Community
    • Conferences
    • Diversity
    • Documentation
    • Living on the edge
    • Releases
    • Security Advisories
    • SymfonyInsight
    • Twig
    • SensioLabs
  • Services
    • SensioLabs services
    • Train developers
    • Manage your project quality
    • Improve your project performance
    • Host Symfony projects
    Deployed on
Follow Symfony
Search by Algolia