@@ -116,29 +116,15 @@ For more information on routing, see :doc:`/routing`.
116
116
.. index ::
117
117
single: Controller; Base controller class
118
118
119
- .. _anchor-name :
120
- :ref:`The Base Controller Classes & Services <the-base-controller-class-services>`
119
+ .. _the-base-controller-class-services :
121
120
122
121
The Base Controller Classes & Services
123
122
--------------------------------------
124
123
125
124
For convenience, Symfony comes with two optional base
126
125
:class: `Symfony\\ Bundle\\ FrameworkBundle\\ Controller\\ Controller ` and
127
126
: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 `_.
142
128
143
129
Add the ``use `` statement atop the ``Controller `` class and then modify
144
130
``LuckyController `` to extend it::
@@ -153,16 +139,15 @@ Add the ``use`` statement atop the ``Controller`` class and then modify
153
139
// ...
154
140
}
155
141
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.
161
144
162
145
.. 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 ``.
166
151
167
152
.. index ::
168
153
single: Controller; Redirecting
@@ -249,40 +234,15 @@ The Symfony templating system and Twig are explained more in the
249
234
250
235
.. _controller-accessing-services :
251
236
252
- Accessing other Services
253
- ~~~~~~~~~~~~~~~~~~~~~~~~
237
+ Fetching Services as Arguments
238
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
254
239
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 >`.
256
241
These are used for rendering templates, sending emails, querying the database and
257
242
any other "work" you can think of.
258
243
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::
286
246
287
247
use Psr\Log\LoggerInterface
288
248
// ...
@@ -293,16 +253,113 @@ it::
293
253
public function numberAction($max, LoggerInterface $logger)
294
254
{
295
255
$logger->info('We are logging!');
296
-
297
256
// ...
298
257
}
299
258
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
+
300
331
.. note ::
301
332
If this isn't working, make sure your controller is registered as a service,
302
333
:ref: `autoconfigured <services-autoconfigure >` and extends either
303
334
:class: `Symfony\\ Bundle\\ FrameworkBundle\\ Controller\\ Controller ` or
304
335
: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 >`.
306
363
307
364
.. index ::
308
365
single: Controller; Managing errors
@@ -379,7 +436,6 @@ Symfony provides a nice session object that you can use to store information
379
436
about the user between requests. By default, Symfony stores the attributes in a
380
437
cookie by using native PHP sessions.
381
438
382
-
383
439
.. versionadded :: 3.3
384
440
The ability to request a ``Session `` instance in controllers was introduced
385
441
in Symfony 3.3.
@@ -646,12 +702,7 @@ and it's a PHP function where you can do anything in order to return the
646
702
final ``Response `` object that will be returned to the user.
647
703
648
704
To 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() ``).
655
706
656
707
In other articles, you'll learn how to use specific services from inside your controller
657
708
that will help you persist and fetch objects from a database, process form submissions,
@@ -676,4 +727,5 @@ Learn more about Controllers
676
727
677
728
controller/*
678
729
730
+ .. _`helper methods` : https://github.com/symfony/symfony/blob/master/src/Symfony/Bundle/FrameworkBundle/Controller/ControllerTrait.php
679
731
.. _`unvalidated redirects security vulnerability` : https://www.owasp.org/index.php/Open_redirect
0 commit comments