@@ -29,11 +29,9 @@ These are the main **advantages** of defining controllers as services:
29
29
These are the main **drawbacks ** of defining controllers as services:
30
30
31
31
* It takes more work to create the controllers because they don't have
32
- automatic access to the services or to the base controller shortcuts ;
32
+ automatic access to the services;
33
33
* The constructor of the controllers can rapidly become too complex because you
34
34
must inject every single dependency needed by them;
35
- * The code of the controllers is more verbose because you can't use the shortcuts
36
- of the base controller and you must replace them with some lines of code.
37
35
38
36
The recommendation from the :doc: `best practices </best_practices/controllers >`
39
37
is also valid for controllers defined as services: avoid putting your business
@@ -83,6 +81,74 @@ Then you can define it as a service as follows:
83
81
84
82
$container->register('app.hello_controller', HelloController::class);
85
83
84
+ Using the controller shortcuts
85
+ ------------------------------
86
+
87
+ To use the traditional controller shortcuts, you can use the
88
+ :class: `Symfony\\ Bundle\\ FrameworkBundle\\ Controller\\ Controller ` class if you
89
+ need to access the container or the
90
+ :class: `Symfony\\ Bundle\\ FrameworkBundle\\ Controller\\ AbstractController ` class
91
+ if you prefer explicit injection (you can't access the container).
92
+
93
+ The example above could be revamped to::
94
+
95
+ // src/AppBundle/Controller/HelloController.php
96
+ namespace AppBundle\Controller;
97
+
98
+ use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
99
+
100
+ class HelloController extends AbstractController
101
+ {
102
+ public function indexAction($name)
103
+ {
104
+ // renders app/Resources/views/hello/index.html.twig
105
+ return $this->render('hello/index.html.twig', array('name' => $name));
106
+ }
107
+ }
108
+
109
+ With the following configuration:
110
+
111
+ .. configuration-block ::
112
+
113
+ .. code-block :: yaml
114
+
115
+ # app/config/services.yml
116
+ services :
117
+ _instanceof :
118
+ Symfony\Bundle\FrameworkBundle\Controller\AbstractController :
119
+ calls : [ [ setContainer, [ '@container' ] ] ]
120
+ tags : [ container.service_subscriber ]
121
+
122
+ AppBundle\Controller\HelloController : ~
123
+
124
+ .. code-block :: xml
125
+
126
+ <!-- app/config/services.xml -->
127
+ <services >
128
+ <instanceof id =" Symfony\Bundle\FrameworkBundle\Controller\AbstractController" >
129
+ <call method =" setController" >
130
+ <argument type =" service" id =" container" />
131
+ </call >
132
+ <tag name =" container.service_subscriber" />
133
+ </instanceof >
134
+
135
+ <service id =" AppBundle\Controller\HelloController" />
136
+ </services >
137
+
138
+ .. code-block :: php
139
+
140
+ // app/config/services.php
141
+ use AppBundle\Controller\HelloController;
142
+ use Symfony\Component\DependencyInjection\Reference;
143
+
144
+ $container->register(HelloController::class)
145
+ ->addMethodCall('setContainer', new Reference('container'));
146
+
147
+ .. versionadded :: 3.3
148
+ The :class: `Symfony\\ Bundle\\ FrameworkBundle\\ Controller\\ AbstractController `
149
+ class was added in Symfony 3.3. Prior to version 3.3, you needed to use the
150
+ base ``Controller `` class or use alternatives to its shortcut methods.
151
+
86
152
Referring to the Service
87
153
------------------------
88
154
@@ -135,14 +201,15 @@ the route ``_controller`` value:
135
201
If your controller implements the ``__invoke() `` method, you can simply
136
202
refer to the service id (``app.hello_controller ``).
137
203
138
- Alternatives to base Controller Methods
139
- ---------------------------------------
204
+ Alternatives to Controller shortcut Methods
205
+ -------------------------------------------
140
206
141
- When using a controller defined as a service, it will most likely not extend
142
- the base ``Controller `` class. Instead of relying on its shortcut methods,
143
- you'll interact directly with the services that you need. Fortunately, this is
144
- usually pretty easy and the base `Controller class source code `_ is a great
145
- source on how to perform many common tasks.
207
+ In case you don't want to inject the container in your controllers,
208
+ it's possible to get ride of controller shortcut methods: you can interact
209
+ directly with the services that you need.
210
+ Fortunately, this is usually pretty easy and the base
211
+ `Controller class source code `_ is a great source on how to perform many common
212
+ tasks.
146
213
147
214
For example, if you want to render a template instead of creating the ``Response ``
148
215
object directly, then your code would look like this if you were extending
0 commit comments