8000 feature #3889 Fixed the section about getting services from a command… · symfony/symfony-docs@8931c36 · GitHub
[go: up one dir, main page]

Skip to content

Commit 8931c36

Browse files
committed
feature #3889 Fixed the section about getting services from a command (javiereguiluz)
This PR was merged into the 2.3 branch. Discussion ---------- Fixed the section about getting services from a command | Q | A | ------------- | --- | Doc fix? | no | New docs? | yes | Applies to | 2.3+ | Fixed tickets | #890 Hopefully this PR fixes one of the oldest errors of the Symfony documentation. Commits ------- 8993beb Linked the cookbook about DIC scopes 0f3c218 Fixed the section about getting services from a command
2 parents 8257be9 + 8993beb commit 8931c36

File tree

1 file changed

+58
-2
lines changed

1 file changed

+58
-2
lines changed

cookbook/console/console_command.rst

Lines changed: 58 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,27 @@ Getting Services from the Service Container
6868
By using :class:`Symfony\\Bundle\\FrameworkBundle\\Command\\ContainerAwareCommand`
6969
as the base class for the command (instead of the more basic
7070
:class:`Symfony\\Component\\Console\\Command\\Command`), you have access to the
71-
service container. In other words, you have access to any configured service.
72-
For example, you could easily extend the task to be translatable::
71+
service container. In other words, you have access to any configured service::
72+
73+
protected function execute(InputInterface $input, OutputInterface $output)
74+
{
75+
$name = $input->getArgument('name');
76+
$logger = $this->getContainer()->get('logger');
77+
78+
$logger->info('Executing command for '.$name);
79+
// ...
80+
}
81+
82+
However, due to the `container scopes </cookbook/service_container/scopes>`_ this
83+
code doesn't work for some services. For instance, if you try to get the ``request``
84+
service or any other service related to it, you'll get the following error:
85+
86+
.. code-block:: text
87+
88+
You cannot create a service ("request") of an inactive scope ("request").
89+
90+
Consider the following example that uses the ``translator`` service to
91+
translate some contents using a console command::
7392

7493
protected function execute(InputInterface $input, OutputInterface $output)
7594
{
@@ -82,6 +101,43 @@ For example, you could easily extend the task to be translatable::
82101
}
83102
}
84103

104+
If you dig into the Translator component classes, you'll see that the ``request``
105+
service is required to get the locale into which the contents are translated::
106+
107+
// vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Translation/Translator.php
108+
public function getLocale()
109+
{
110+
if (null === $this->locale && $this->container->isScopeActive('request')
111+
&& $this->container->has('request')) {
112+
$this->locale = $this->container->get('request')->getLocale();
113+
}
114+
115+
return $this->locale;
116+
}
117+
118+
Therefore, when using the ``translator`` service inside a command, you'll get the
119+
previous *"You cannot create a service of an inactive scope"* error message.
120+
The solution in this case is as easy as setting the locale value explicitly
121+
before translating contents::
122+
123+
protected function execute(InputInterface $input, OutputInterface $output)
124+
{
125+
$name = $input->getArgument('name');
126+
$locale = $input->getArgument('locale');
127+
128+
$translator = $this->getContainer()->get('translator');
129+
$translator->setLocale($locale);
130+
131+
if ($name) {
132+
$output->writeln($translator->trans('Hello %name%!', array('%name%' => $name)));
133+
} else {
134+
$output->writeln($translator->trans('Hello!'));
135+
}
136+
}
137+
138+
However for other services the solution might be more complex. For more details,
139+
see :doc:`/cookbook/service_container/scopes`.
140+
85141
Testing Commands
86142
----------------
87143

0 commit comments

Comments
 (0)
0