Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitc75b1a7

Browse files
committed
featuresymfony#3621 [Console] Command as service (gnugat)
This PR was merged into the 2.4 branch.Discussion----------[Console] Command as service| Q | A| ------------- | ---| Doc fix? | yes| New docs? | no| Applies to | 2.4+| Fixed tickets | N/ACommand as a service can be useful to give access to services andconfiguration parameters in the `configure` method.A simple use case: you want to allow the user to set an option's defaultvalue in the `app/config/parameters.yml` file. Or the default valueneeds to be computed by a service (database retrieval for instance).With a `ContainerAwareCommand`, this wouldn't be possible because the`configure` method is called from the constructor, so the containerisn't set yet.Original PR:symfony#3620Commits-------c8fe610 Moved back and listened to@weaverryane8b3320 Took into account@cordoval's feedback11bfe50 Added warning about performances6a7a25f Fixed@wouterj's feedbacke137951 Created a new articlecdd534a Added@lsmith77 and@dbu use casesa7b916e Fixed typos spotted by@cordovala055140 Took@wouterj's advices into account947ad92 [Console] Adding use cases to command as service
2 parentsd8182fc +c8fe610 commitc75b1a7

File tree

3 files changed

+127
-48
lines changed

3 files changed

+127
-48
lines changed
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
..index::
2+
single: Console; Commands as Services
3+
4+
How to Define Commands as Services
5+
==================================
6+
7+
..versionadded::2.4
8+
Support for registering commands in the service container was introduced in
9+
version 2.4.
10+
11+
By default, Symfony will take a look in the ``Command`` directory of each
12+
bundle and automatically register your commands. If a command extends the
13+
:class:`Symfony\\Bundle\\FrameworkBundle\\Command\\ContainerAwareCommand`,
14+
Symfony will even inject the container.
15+
While making life easier, this has some limitations:
16+
17+
* Your command must live in the ``Command`` directory;
18+
* There's no way to conditionally register your service based on the environment
19+
or availability of some dependencies;
20+
* You can't access the container in the ``configure()`` method (because
21+
``setContainer`` hasn't been called yet);
22+
* You can't use the same class to create many commands (i.e. each with
23+
different configuration).
24+
25+
To solve these problems, you can register your command as a service and tag it
26+
with ``console.command``:
27+
28+
..configuration-block::
29+
30+
..code-block::yaml
31+
32+
# app/config/config.yml
33+
services:
34+
acme_hello.command.my_command:
35+
class:Acme\HelloBundle\Command\MyCommand
36+
tags:
37+
-{ name: console.command }
38+
39+
..code-block::xml
40+
41+
<!-- app/config/config.xml-->
42+
<?xml version="1.0" encoding="UTF-8" ?>
43+
<containerxmlns="http://symfony.com/schema/dic/services"
44+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
45+
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
46+
47+
<services>
48+
<serviceid="acme_hello.command.my_command"
49+
class="Acme\HelloBundle\Command\MyCommand">
50+
<tagname="console.command" />
51+
</service>
52+
</services>
53+
</container>
54+
55+
..code-block::php
56+
57+
// app/config/config.php
58+
$container
59+
->register('acme_hello.command.my_command', 'Acme\HelloBundle\Command\MyCommand')
60+
->addTag('console.command')
61+
;
62+
63+
Using Dependencies and Parameters to Set Default Values for Options
64+
-------------------------------------------------------------------
65+
66+
Imagine you want to provide a default value for the ``name`` option. You could
67+
pass one of the following as the 5th argument of ``addOption()``:
68+
69+
* a hardcoded string;
70+
* a container parameter (e.g. something from parameters.yml);
71+
* a value computed by a service (e.g. a repository).
72+
73+
By extending ``ContainerAwareCommand``, only the first is possible, because you
74+
can't access the container inside the ``configure()`` method. Instead, inject
75+
any parameter or service you need into the constructor. For example, suppose you
76+
have some ``NameRepository`` service that you'll use to get your default value::
77+
78+
// src/Acme/DemoBundle/Command/GreetCommand.php
79+
namespace Acme\DemoBundle\Command;
80+
81+
use Acme\DemoBundle\Entity\NameRepository;
82+
use Symfony\Component\Console\Command\Command;
83+
use Symfony\Component\Console\Input\InputInterface;
84+
use Symfony\Component\Console\Input\InputOption;
85+
use Symfony\Component\Console\Output\OutputInterface;
86+
87+
class GreetCommand extends Command
88+
{
89+
protected $nameRepository;
90+
91+
public function __construct(NameRepository $nameRepository)
92+
{
93+
$this->nameRepository = $nameRepository;
94+
}
95+
96+
protected function configure()
97+
{
98+
$defaultName = $this->nameRepository->findLastOne();
99+
100+
$this
101+
->setName('demo:greet')
102+
->setDescription('Greet someone')
103+
->addOption('name', '-n', InputOption::VALUE_REQUIRED, 'Who do you want to greet?', $defaultName)
104+
;
105+
}
106+
107+
protected function execute(InputInterface $input, OutputInterface $output)
108+
{
109+
$name = $input->getOption('name');
110+
111+
$output->writeln($name);
112+
}
113+
}
114+
115+
Now, just update the arguments of your service configuration like normal to
116+
inject the ``NameRepository``. Great, you now have a dynamic default value!
117+
118+
..caution::
119+
120+
Be careful not to actually do any work in ``configure`` (e.g. make database
121+
queries), as your code will be run, even if you're using the console to
122+
execute a different command.

‎cookbook/console/console_command.rst‎

Lines changed: 4 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -65,55 +65,11 @@ This command will now automatically be available to run:
6565
.. _cookbook-console-dic:
6666

6767
Register Commands in the Service Container
68-
------------------------------------------
69-
70-
..versionadded::2.4
71-
Support for registering commands in the service container was added in
72-
version 2.4.
73-
74-
Instead of putting your command in the ``Command`` directory and having Symfony
75-
auto-discover it for you, you can register commands in the service container
76-
using the ``console.command`` tag:
77-
78-
..configuration-block::
79-
80-
..code-block::yaml
81-
82-
# app/config/config.yml
83-
services:
84-
acme_hello.command.my_command:
85-
class:Acme\HelloBundle\Command\MyCommand
86-
tags:
87-
-{ name: console.command }
88-
89-
..code-block::xml
90-
91-
<!-- app/config/config.xml-->
92-
<?xml version="1.0" encoding="UTF-8" ?>
93-
<containerxmlns="http://symfony.com/schema/dic/services"
94-
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
95-
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
96-
97-
<serviceid="acme_hello.command.my_command"
98-
class="Acme\HelloBundle\Command\MyCommand">
99-
<tagname="console.command" />
100-
</service>
101-
</container>
102-
103-
..code-block::php
104-
105-
// app/config/config.php
106-
107-
$container
108-
->register('acme_hello.command.my_command', 'Acme\HelloBundle\Command\MyCommand')
109-
->addTag('console.command')
110-
;
111-
112-
..tip::
68+
-------------------------------------------
11369

114-
Registering your command asa service gives you more control over its
115-
location and the services that are injected into it. But, there are no
116-
functional advantages, so you don't need to register your command as a service.
70+
Just like controllers, commands can be declared asservices. See the
71+
:doc:`dedicated cookbook entry</cookbook/console/commands_as_services>`
72+
for details.
11773

11874
Getting Services from the Service Container
11975
-------------------------------------------

‎cookbook/console/index.rst‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,4 @@ Console
88
usage
99
sending_emails
1010
logging
11+
commands_as_services

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp