Skip to content

Commit 86ab47a

Browse files
committed
more type changes
1 parent 61166c1 commit 86ab47a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+633
-1608
lines changed

_build/redirection_map

+2
Original file line numberDiff line numberDiff line change
@@ -336,3 +336,5 @@
336336
/components/dependency_injection/autowiring /service_container/autowiring
337337
/event_dispatcher/class_extension /event_dispatcher
338338
/security/target_path /security
339+
/service_container/third_party /service_container
340+
/templating/templating_service /templates

bundles/best_practices.rst

+8-1
Original file line numberDiff line numberDiff line change
@@ -384,7 +384,14 @@ If the bundle defines services, they must be prefixed with the bundle alias.
384384
For example, AcmeBlogBundle services must be prefixed with ``acme_blog``.
385385

386386
In addition, services not meant to be used by the application directly, should
387-
be :ref:`defined as private <container-private-services>`.
387+
be :ref:`defined as private <container-private-services>`. For public services,
388+
:ref:`aliases should be created <service-autowiring-alias>` from the interface/class
389+
to the service id. For example, in MonlogBundle, an alias is created from
390+
``Psr\Log\LoggerInterface`` to ``logger`` so that the ``LoggerInterface`` type-hint
391+
can be used for autowiring.
392+
393+
Services should not use autowiring or autoconfiguration. Instead, all services should
394+
be defined explicitly.
388395

389396
.. seealso::
390397

bundles/extension.rst

+6
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,12 @@ read more about it, see the ":doc:`/bundles/configuration`" article.
129129
Adding Classes to Compile
130130
-------------------------
131131

132+
.. note::
133+
134+
The ``addClassesToCompile()`` method was deprecated in Symfony 3.3, and will
135+
be removed in Symfony 4.0. If you want to use this method and be compatible
136+
with Symfony 4.0, check to see if the method exists before calling it.
137+
132138
Symfony creates a big ``classes.php`` file in the cache directory to aggregate
133139
the contents of the PHP classes that are used in every request. This reduces the
134140
I/O operations and increases the application performance.

console/command_in_controller.rst

+2-2
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,12 @@ Run this command from inside your controller via::
3232
use Symfony\Component\Console\Input\ArrayInput;
3333
use Symfony\Component\Console\Output\BufferedOutput;
3434
use Symfony\Component\HttpFoundation\Response;
35+
use Symfony\Component\HttpKernel\KernelInterface;
3536

3637
class SpoolController extends Controller
3738
{
38-
public function sendSpoolAction($messages = 10)
39+
public function sendSpoolAction($messages = 10, KernelInterface $kernel)
3940
{
40-
$kernel = $this->get('kernel');
4141
$application = new Application($kernel);
4242
$application->setAutoExit(false);
4343

console/commands_as_services.rst

+29-138
Original file line numberDiff line numberDiff line change
@@ -4,173 +4,64 @@
44
How to Define Commands as Services
55
==================================
66

7-
By default, Symfony will take a look in the ``Command`` directory of each
8-
bundle and automatically register your commands. If a command extends the
9-
:class:`Symfony\\Bundle\\FrameworkBundle\\Command\\ContainerAwareCommand`,
10-
Symfony will even inject the container.
11-
While making life easier, this has some limitations:
7+
If you're using the :ref:`default services.yml configuration <service-container-services-load-example>`,
8+
your command classes are already registered as services. Great! This is the recommended
9+
setup, but it's not required. Symfony also looks in the ``Command`` directory of
10+
each bundle and automatically registers those classes as commands.
1211

13-
* Your command must live in the ``Command`` directory;
14-
* There's no way to conditionally register your command based on the environment
15-
or availability of some dependencies;
16-
* You can't access the container in the ``configure()`` method (because
17-
``setContainer()`` hasn't been called yet);
18-
* You can't use the same class to create many commands (i.e. each with
19-
different configuration).
12+
.. note::
2013

21-
To solve these problems, you can register your command as a service and tag it
22-
with ``console.command``:
14+
You can also manually register your command as a service by configure the service
15+
and :doc:`tagging it </service_container/tags>` with ``console.command``.
2316

24-
.. configuration-block::
17+
In either case, if your class extends :class:`Symfony\\Bundle\\FrameworkBundle\\Command\\ContainerAwareCommand`,
18+
you can access public services via ``$this->getContainer()->get('SERVICE_ID')``.
2519

26-
.. code-block:: yaml
20+
But if your class is registered as a service, you can instead access services by
21+
using normal :ref:`dependency injection <services-constructor-injection>`.
2722

28-
# app/config/config.yml
29-
services:
30-
AppBundle\Command\MyCommand: [console.command]
23+
For example, suppose you want to log something from within your command::
3124

32-
.. code-block:: xml
33-
34-
<!-- app/config/config.xml -->
35-
<?xml version="1.0" encoding="UTF-8" ?>
36-
<container xmlns="http://symfony.com/schema/dic/services"
37-
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
38-
xsi:schemaLocation="http://symfony.com/schema/dic/services
39-
http://symfony.com/schema/dic/services/services-1.0.xsd">
40-
41-
<services>
42-
<service id="AppBundle\Command\MyCommand">
43-
<tag name="console.command" />
44-
</service>
45-
</services>
46-
47-
</container>
48-
49-
.. code-block:: php
50-
51-
// app/config/config.php
52-
use AppBundle\Command\MyCommand;
53-
54-
$container->register(MyCommand::class)
55-
->addTag('console.command')
56-
;
57-
58-
Using Dependencies and Parameters to Set Default Values for Options
59-
-------------------------------------------------------------------
60-
61-
Imagine you want to provide a default value for the ``name`` option. You could
62-
pass one of the following as the 5th argument of ``addOption()``:
63-
64-
* a hardcoded string;
65-
* a container parameter (e.g. something from ``parameters.yml``);
66-
* a value computed by a service (e.g. a repository).
67-
68-
By extending ``ContainerAwareCommand``, only the first is possible, because you
69-
can't access the container inside the ``configure()`` method. Instead, inject
70-
any parameter or service you need into the constructor. For example, suppose you
71-
store the default value in some ``%command.default_name%`` parameter::
72-
73-
// src/AppBundle/Command/GreetCommand.php
7425
namespace AppBundle\Command;
7526

27+
use Psr\Log\LoggerInterface;
7628
use Symfony\Component\Console\Command\Command;
7729
use Symfony\Component\Console\Input\InputInterface;
78-
use Symfony\Component\Console\Input\InputOption;
7930
use Symfony\Component\Console\Output\OutputInterface;
8031

81-
class GreetCommand extends Command
32+
class SunshineCommand extends Command
8233
{
83-
protected $defaultName;
34+
private $logger;
8435

85-
public function __construct($defaultName)
36+
public function __construct(LoggerInterface $logger)
8637
{
87-
$this->defaultName = $defaultName;
38+
$this->logger = $logger;
8839

40+
// you *must* call the parent constructor
8941
parent::__construct();
9042
}
9143

9244
protected function configure()
9345
{
94-
// try to avoid work here (e.g. database query)
95-
// this method is *always* called - see warning below
96-
$defaultName = $this->defaultName;
97-
9846
$this
99-
->setName('demo:greet')
100-
->setDescription('Greet someone')
101-
->addOption(
102-
'name',
103-
'-n',
104-
InputOption::VALUE_REQUIRED,
105-
'Who do you want to greet?',
106-
$defaultName
107-
)
108-
;
47+
->setName('app:sunshine')
48+
->setDescription('Hello PhpStorm');
10949
}
11050

11151
protected function execute(InputInterface $input, OutputInterface $output)
11252
{
113-
$name = $input->getOption('name');
114-
115-
$output->writeln($name);
53+
$this->logger->info('Waking up the sun');
54+
// ...
11655
}
11756
}
11857

119-
Now, just update the arguments of your service configuration like normal to
120-
inject the ``command.default_name`` parameter:
121-
122-
.. configuration-block::
123-
124-
.. code-block:: yaml
125-
126-
# app/config/config.yml
127-
parameters:
128-
command.default_name: Javier
129-
130-
services:
131-
AppBundle\Command\MyCommand:
132-
arguments: ["%command.default_name%"]
133-
tags: [console.command]
134-
135-
.. code-block:: xml
136-
137-
<!-- app/config/config.xml -->
138-
<?xml version="1.0" encoding="UTF-8" ?>
139-
<container xmlns="http://symfony.com/schema/dic/services"
140-
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
141-
xsi:schemaLocation="http://symfony.com/schema/dic/services
142-
http://symfony.com/schema/dic/services/services-1.0.xsd">
143-
144-
<parameters>
145-
<parameter key="command.default_name">Javier</parameter>
146-
</parameters>
147-
148-
<services>
149-
<service class="AppBundle\Command\MyCommand">
150-
<argument>%command.default_name%</argument>
151-
<tag name="console.command" />
152-
</service>
153-
</services>
154-
155-
</container>
156-
157-
.. code-block:: php
158-
159-
// app/config/config.php
160-
use AppBundle\Command\MyCommand;
161-
162-
$container->setParameter('command.default_name', 'Javier');
163-
164-
$container
165-
->register(MyCommand::class)
166-
->setArguments(array('%command.default_name%'))
167-
->addTag('console.command')
168-
;
169-
170-
Great, you now have a dynamic default value!
58+
If you're using the :ref:`default services.yml configuration <service-container-services-load-example>`,
59+
the command class will automatically be registered as a service and passed the ``$logger``
60+
argument (thanks to autowiring). In other words, *just* by creating this class, everything
61+
works! You can call the ``app:sunshine`` command and start logging.
17162

17263
.. caution::
17364

174-
Be careful not to actually do any work in ``configure`` (e.g. make database
175-
queries), as your code will be run, even if you're using the console to
176-
execute a different command.
65+
You *do* have access to services in ``configure()``. However, try to avoid doing
66+
any work (e.g. making database queries), as that code will be run, even if you're
67+
using the console to execute a different command.

console/logging.rst

+3
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,6 @@ listener for the console.
1010

1111
Starting from Symfony 3.3, the Console component provides automatic error and
1212
exception logging.
13+
14+
You can of course also access and use the :doc:`logger </logging>` service to
15+
log messages.

0 commit comments

Comments
 (0)