Symfony
sponsored by SensioLabs
Menu
  • About
  • Documentation
  • Screencasts
  • Cloud
  • Certification
  • Community
  • Businesses
  • News
  • Download
  1. Home
  2. Documentation
  3. Cookbook
  4. Console
  5. How to Define Commands as Services
  • Documentation
  • Book
  • Reference
  • Bundles
  • Cloud
Search by Algolia
  • Using Dependencies and Parameters to Set Default Values for Options

How to Define Commands as Services

Edit this page

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

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

How to Define Commands as Services

2.4

Support for registering commands in the service container was introduced in Symfony 2.4.

By default, Symfony will take a look in the Command directory of each bundle and automatically register your commands. If a command extends the ContainerAwareCommand, Symfony will even inject the container. While making life easier, this has some limitations:

  • Your command must live in the Command directory;
  • There's no way to conditionally register your service based on the environment or availability of some dependencies;
  • You can't access the container in the configure() method (because setContainer hasn't been called yet);
  • You can't use the same class to create many commands (i.e. each with different configuration).

To solve these problems, you can register your command as a service and tag it with console.command:

  • YAML
  • XML
  • PHP
1
2
3
4
5
6
# app/config/config.yml
services:
    acme_hello.command.my_command:
        class: Acme\HelloBundle\Command\MyCommand
        tags:
            -  { name: console.command }
1
2
3
4
5
6
7
8
9
10
11
12
13
<!-- app/config/config.xml -->
<?xml version="1.0" encoding="UTF-8" ?>
<container xmlns="http://symfony.com/schema/dic/services"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">

    <services>
        <service id="acme_hello.command.my_command"
            class="Acme\HelloBundle\Command\MyCommand">
            <tag name="console.command" />
        </service>
    </services>
</container>
1
2
3
4
5
// app/config/config.php
$container
    ->register('acme_hello.command.my_command', 'Acme\HelloBundle\Command\MyCommand')
    ->addTag('console.command')
;

Using Dependencies and Parameters to Set Default Values for Options

Imagine you want to provide a default value for the name option. You could pass one of the following as the 5th argument of addOption():

  • a hardcoded string;
  • a container parameter (e.g. something from parameters.yml);
  • a value computed by a service (e.g. a repository).

By extending ContainerAwareCommand, only the first is possible, because you can't access the container inside the configure() method. Instead, inject any parameter or service you need into the constructor. For example, suppose you have some NameRepository service that you'll use to get your default value:

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
// src/Acme/DemoBundle/Command/GreetCommand.php
namespace Acme\DemoBundle\Command;

use Acme\DemoBundle\Entity\NameRepository;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;

class GreetCommand extends Command
{
    protected $nameRepository;

    public function __construct(NameRepository $nameRepository)
    {
        $this->nameRepository = $nameRepository;
        
        parent::__construct();
    }

    protected function configure()
    {
        $defaultName = $this->nameRepository->findLastOne();

        $this
            ->setName('demo:greet')
            ->setDescription('Greet someone')
            ->addOption('name', '-n', InputOption::VALUE_REQUIRED, 'Who do you want to greet?', $defaultName)
        ;
    }

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

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

Now, just update the arguments of your service configuration like normal to inject the NameRepository. Great, you now have a dynamic default value!

Caution

Be careful not to actually do any work in configure (e.g. make database queries), as your code will be run, even if you're using the console to execute a different command.

This work, including the code samples, is licensed under a Creative Commons BY-SA 3.0 license.
We stand with Ukraine.
Version:
Online Sylius certification, take it now!

Online Sylius certification, take it now!

Code consumes server resources. Blackfire tells you how

Code consumes server resources. Blackfire tells you how

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

Avatar of Rafael Mello, a Symfony contributor

Thanks Rafael Mello (@merorafael) for being a Symfony contributor

4 commits • 34 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