@@ -116,29 +116,15 @@ For more information on routing, see :doc:`/routing`.
116116..index ::
117117 single: Controller; Base controller class
118118
119- .. _anchor-name :
120- :ref:`The Base Controller Classes & Services <the-base-controller-class-services>`
119+ .. _the-base-controller-class-services :
121120
122121The Base Controller Classes & Services
123122--------------------------------------
124123
125124For convenience, Symfony comes with two optional base
126125:class: `Symfony\\ Bundle\\ FrameworkBundle\\ Controller\\ Controller ` and
127126:class: `Symfony\\ Bundle\\ FrameworkBundle\\ Controller\\ AbstractController `
128- classes.
129- If you extend one or the other, this won't change anything about how your
130- controller works, but you'll get access to a number of **helper methods **.
131-
132- The base ``Controller `` also allows you to access the **service container ** (see:ref: `controller-accessing-services `): an
133- array-like object that gives you access to every useful object in the
134- system. These useful objects are called **services **, and Symfony ships
135- with a service object that can render Twig templates, another that can
136- log messages and many more.
137-
138- On the other hand, the ``AbstractController `` prevents you from accessing the
139- **service container **. When you need an external dependency, this forces you to
140- write a code more robust as you have to explicitly define your dependencies by
141- using:doc: `the controller as a service </controller/service >`.
127+ classes. You can extend either to get access to a number of `helper methods `_.
142128
143129Add the ``use `` statement atop the ``Controller `` class and then modify
144130``LuckyController `` to extend it::
@@ -153,16 +139,15 @@ Add the ``use`` statement atop the ``Controller`` class and then modify
153139 // ...
154140 }
155141
156- Helper methods are just shortcuts to using core Symfony functionality
157- that's available to you with or without the use of the base
158- controller classes. A great way to see the core functionality in
159- action is to look in the
160- :class: `Symfony\\ Bundle\\ FrameworkBundle\\ Controller\\ Controller ` class.
142+ That's it! You now have access to methods like:ref: `$this->render() <controller-rendering-templates >`
143+ and many others that you'll learn about next.
161144
162145..tip ::
163- If you know what you're doing, you can alternatively extend
164- :class: `Symfony\\ Bundle\\ FrameworkBundle\\ Controller\\ AbstractController `. It
165- has all the same shortcuts, but does not have a ```$this->container `` property.
146+
147+ You can extend either ``Controller `` or ``AbstractController ``. The difference
148+ is that when you extend ``AbstractController ``, you can't access services directly
149+ via ``$this->get() `` or ``$this->container->get() ``. This forces you to write
150+ more robust code to access services, but if you're not use, use ``Controller ``.
166151
167152..index ::
168153 single: Controller; Redirecting
@@ -249,40 +234,15 @@ The Symfony templating system and Twig are explained more in the
249234
250235.. _controller-accessing-services :
251236
252- Accessing other Services
253- ~~~~~~~~~~~~~~~~~~~~~~~~
237+ Fetching Services as Arguments
238+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
254239
255- Symfony comes packed with a lot of useful objects, called:doc: `services </service_container >`.
240+ Symfony comes* packed * with a lot of useful objects, called:doc: `services </service_container >`.
256241These are used for rendering templates, sending emails, querying the database and
257242any other "work" you can think of.
258243
259- When extending the base ``Controller `` class, you can access any Symfony service
260- via the:method: `Symfony\\ Bundle\\ FrameworkBundle\\ Controller\\ Controller::get `
261- method. Here are several common services you might need::
262-
263- $templating = $this->get('templating');
264-
265- $router = $this->get('router');
266-
267- $mailer = $this->get('mailer');
268-
269- // you can also fetch parameters
270- $someParameter = $this->getParameter('some_parameter');
271-
272- What other services exist? To list all services, use the ``debug:container ``
273- console command:
274-
275- ..code-block ::terminal
276-
277- $ php bin/console debug:container
278-
279- For more information, see the:doc: `/service_container ` article.
280-
281- Services as Controller Arguments
282- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
283-
284- You can also tell Symfony to pass your a service as a controller argument by type-hinting
285- it::
244+ If you need a service, just type-hint an argument with its class (or interface) name.
245+ Symfony will automatically pass you the service you need::
286246
287247 use Psr\Log\LoggerInterface
288248 // ...
@@ -293,16 +253,113 @@ it::
293253 public function numberAction($max, LoggerInterface $logger)
294254 {
295255 $logger->info('We are logging!');
296-
297256 // ...
298257 }
299258
259+ Awesome!
260+
261+ What other services exist? Each page of the documentation will reveal more and more
262+ services you can use. To list *all * services, use the ``debug:container `` console
263+ command:
264+
265+ ..code-block ::terminal
266+
267+ $ php bin/console debug:container
268+
269+ If need to control the *exact * value of an argument, you can override your controller's
270+ service config:
271+
272+ ..configuration-block ::
273+
274+ ..code-block ::yaml
275+
276+ # app/config/services.yml
277+ services :
278+ # ...
279+
280+ # explicitly configure the service
281+ AppBundle\Controller\LuckyController :
282+ public :true
283+ tags :
284+ # add multiple tags to controller multiple args
285+ -name :controller.service_arguments
286+ action :numberAction
287+ argument :logger
288+ # pass this specific service id
289+ id :monolog.logger.doctrine
290+
291+ ..code-block ::xml
292+
293+ <!-- app/config/services.xml-->
294+ <?xml version =" 1.0" encoding =" UTF-8" ?>
295+ <container xmlns =" http://symfony.com/schema/dic/services"
296+ xmlns : xsi =" http://www.w3.org/2001/XMLSchema-instance"
297+ xsi : schemaLocation =" http://symfony.com/schema/dic/services
298+ http://symfony.com/schema/dic/services/services-1.0.xsd" >
299+
300+ <services >
301+ <!-- ...-->
302+
303+ <!-- Explicitly configure the service-->
304+ <service id =" AppBundle\Controller\LuckyController" public =" true" >
305+ <tag
306+ name =" controller.service_arguments"
307+ action =" numberAction"
308+ argument =" logger"
309+ id =" monolog.logger.doctrine"
310+ />
311+ </service >
312+ </services >
313+ </container >
314+
315+ ..code-block ::php
316+
317+ // app/config/services.php
318+ use AppBundle\Controller\LuckyController;
319+
320+ $container->register(LuckyController::class)
321+ ->setPublic(true)
322+ ->addTag('controller.service_arguments', [
323+ 'action' => 'numberAction',
324+ 'argument' => 'logger',
325+ 'id' => 'monolog.logger.doctrine',
326+ ])
327+ ;
328+
329+ For more information about services, see the:doc: `/service_container ` article.
330+
300331..note ::
301332 If this isn't working, make sure your controller is registered as a service,
302333:ref: `autoconfigured <services-autoconfigure >` and extends either
303334:class: `Symfony\\ Bundle\\ FrameworkBundle\\ Controller\\ Controller ` or
304335:class: `Symfony\\ Bundle\\ FrameworkBundle\\ Controller\\ AbstractController `. Or,
305- you can tag it manually with ``controller.service_arguments ``.
336+ you can tag your service manually with ``controller.service_arguments ``.
337+
338+ .. _accessing-other-services :
339+ .. _controller-access-services-directly :
340+
341+ Accessing the Container Directly
342+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
343+
344+ If extending the base ``Controller `` class, you can access any Symfony service
345+ via the:method: `Symfony\\ Bundle\\ FrameworkBundle\\ Controller\\ Controller::get `
346+ method. Here are several common services you might need::
347+
348+ $templating = $this->get('templating');
349+
350+ $router = $this->get('router');
351+
352+ $mailer = $this->get('mailer');
353+
354+ // you can also fetch parameters
355+ $someParameter = $this->getParameter('some_parameter');
356+
357+ If you receive an eror like:
358+
359+ You have requested a non-existent service "my_service_id"
360+
361+ Check to make sure the service exists (use:ref: `debug:container <container-debug-container >`)
362+ and that it's:ref: `public <container-public >`.
306363
307364..index ::
308365 single: Controller; Managing errors
@@ -379,7 +436,6 @@ Symfony provides a nice session object that you can use to store information
379436about the user between requests. By default, Symfony stores the attributes in a
380437cookie by using native PHP sessions.
381438
382-
383439..versionadded ::3.3
384440 The ability to request a ``Session `` instance in controllers was introduced
385441 in Symfony 3.3.
@@ -646,12 +702,7 @@ and it's a PHP function where you can do anything in order to return the
646702final ``Response `` object that will be returned to the user.
647703
648704To make life easier, you'll probably extend the base ``Controller `` class because
649- this gives two things:
650-
651- A) Shortcut methods (like ``render() `` and ``redirectToRoute() ``);
652-
653- B) Access to *all * of the useful objects (services) in the system via the
654- :ref: `get() <controller-accessing-services >` method.
705+ this gives access to shortcut methods (like ``render() `` and ``redirectToRoute() ``).
655706
656707In other articles, you'll learn how to use specific services from inside your controller
657708that will help you persist and fetch objects from a database, process form submissions,
@@ -676,4 +727,5 @@ Learn more about Controllers
676727
677728controller/*
678729
730+ .. _`helper methods` :https://github.com/symfony/symfony/blob/master/src/Symfony/Bundle/FrameworkBundle/Controller/ControllerTrait.php
679731.. _`unvalidated redirects security vulnerability` :https://www.owasp.org/index.php/Open_redirect