Talk To Us For FREE

We are in the Business of Support and that starts before you even become a client.


  • Please prove you are human by selecting the Cup.

Symfony 2 – How to create console command

Categories : Article, Symfony

For automatically creating console commands with Symfony 2, you will need to create a Command directory within your bundle and also create a PHP file with command.php suffix. This will be required for each command that you want to provide.

The following example shows how to extend the AcmeDemoBundle to greet you from the command line, create GreetCommand.php

// src/Acme/DemoBundle/Command/GreetCommand.php
namespace Acme\DemoBundle\Command;

use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
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 ContainerAwareCommand
{
    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);
    }
}

The command will now be able to automatically run.
Commands can also be declared as services – similar to controllers.

How to get services from the service container
You can get access to the service container by using the ContainerAwareCommand. This will enable you to have access to any configured service.

protected function execute(InputInterface $input, OutputInterface $output)
{
    $name = $input->getArgument('name');
    $logger = $this->getContainer()->get('logger');

    $logger->info('Executing command for '.$name);
    // ...
}

For some services, this code does not work, due to container scopes. If you try to get the request service, the following error occurs:
You cannot create a service (“request”) of an inactive scope (“request”).

Check the following example for the translator service

protected function execute(InputInterface $input, OutputInterface $output)
{
    $name = $input->getArgument('name');
    $translator = $this->getContainer()->get('translator');
    if ($name) {
        $output->writeln($translator->trans('Hello %name%!', array('%name%' => $name)));
    } else {
        $output->writeln($translator->trans('Hello!'));
    }
}

Looking further into the translator components, you’ll see that the request service is required

// vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Translation/Translator.php
public function getLocale()
{
    if (null === $this->locale && $this->container->isScopeActive('request')
        && $this->container->has('request')) {
        $this->locale = $this->container->get('request')->getLocale();
    }

    return $this->locale;
}

When using the translator service, inside a command, you get the following error: You cannot create a service of an inactive scope”
The solution is easy.

protected function execute(InputInterface $input, OutputInterface $output)
{
    $name = $input->getArgument('name');
    $locale = $input->getArgument('locale');

    $translator = $this->getContainer()->get('translator');
    $translator->setLocale($locale);

    if ($name) {
        $output->writeln($translator->trans('Hello %name%!', array('%name%' => $name)));
    } else {
        $output->writeln($translator->trans('Hello!'));
    }
}

Testing Commands

While testing, Symfony\Bundle\FrameworkBundle\Console\Application should be used instead of Symfony\Component\Console\Application:
use Symfony\Component\Console\Tester\CommandTester;
use Symfony\Bundle\FrameworkBundle\Console\Application;
use Acme\DemoBundle\Command\GreetCommand;

class ListCommandTest extends \PHPUnit_Framework_TestCase
{
    public function testExecute()
    {
        // mock the Kernel or create one depending on your needs
        $application = new Application($kernel);
        $application->add(new GreetCommand());

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

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

        // ...
    }
}

You can extend your test from KernelTestCase to be able to use the fully set up service container for your console test.

use Symfony\Component\Console\Tester\CommandTester;
use Symfony\Bundle\FrameworkBundle\Console\Application;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
use Acme\DemoBundle\Command\GreetCommand;

class ListCommandTest extends KernelTestCase
{
    public function testExecute()
    {
        $kernel = $this->createKernel();
        $kernel->boot();

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

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

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

        // ...
    }
}

To be able to use the fully set up service container for your console tests you can extend your test from KernelTestCase:

[Total: 0    Average: 0/5]

Client Saying

If you're starting a new business or want to upgrade an existing site, I strongly recommend…
Mr. Manjesh Singh
CTO
Daniel Coburn, the president of Bragshare.com gives the honest opinion regarding his experience working with Brainvire…
Mr. Daniel Coburn
Chad Gundry, the CEO of Bragshare.com says that he has worked extensively with Brainvire team since…
Mr. Chad Gundry
The best thing about Brainvire is Compatibility. Whenever we have a query Brainvire is always ready…
Mr Craig Agranoff
Brainvire is a professional company with professional developers who understand the problems that we are facing…
Mr. Clarke Verdel

Latest Happenings

  • 17 Mar 2017
    Brainvire - Walmart Collaboration Hits Another Retail Height [ + ]
  • 03 Mar 2017
    Brainvire’s Vision for Becoming the Global Mobile Dominant Strengthens with MWC17 [ + ]
Enquiry