@@ -90,6 +90,8 @@ to the events discussed below::
90
90
use Symfony\Component\HttpFoundation\Request;
91
91
use Symfony\Component\HttpKernel\HttpKernel;
92
92
use Symfony\Component\EventDispatcher\EventDispatcher;
93
+ use Symfony\Component\HttpFoundation\RequestStack;
94
+ use Symfony\Component\HttpKernel\Controller\ArgumentResolver;
93
95
use Symfony\Component\HttpKernel\Controller\ControllerResolver;
94
96
95
97
// create the Request object
@@ -98,10 +100,12 @@ to the events discussed below::
98
100
$dispatcher = new EventDispatcher();
99
101
// ... add some event listeners
100
102
101
- // create your controller resolver
102
- $resolver = new ControllerResolver();
103
+ // create your controller and argument resolvers
104
+ $controllerResolver = new ControllerResolver();
105
+ $argumentResolver = new ArgumentResolver();
106
+
103
107
// instantiate the kernel
104
- $kernel = new HttpKernel($dispatcher, $resolver );
108
+ $kernel = new HttpKernel($dispatcher, $controllerResolver, new RequestStack(), $argumentResolver );
105
109
106
110
// actually execute the kernel, which turns the request into a response
107
111
// by dispatching events, calling a controller, and returning the response
@@ -118,6 +122,14 @@ See ":ref:`http-kernel-working-example`" for a more concrete implementation.
118
122
For general information on adding listeners to the events below, see
119
123
:ref: `http-kernel-creating-listener `.
120
124
125
+
126
+ .. caution ::
127
+
128
+ As of 3.1 the :class: `Symfony\\ Component\\ Httpkernel\\ HttpKernel ` accepts a fourth argument, which
129
+ must be an instance of :class: `Symfony\\ Component\\ Httpkernel\\ Controller\\ ArgumentResolverInterface `.
130
+ In 4.0 this argument will become mandatory and the :class: `Symfony\\ Component\\ Httpkernel\\ HttpKernel `
131
+ will no longer be able to fall back to the :class: `Symfony\\ Component\\ Httpkernel\\ Controller\\ ControllerResolver `.
132
+
121
133
.. seealso ::
122
134
123
135
There is a wonderful tutorial series on using the HttpKernel component and
@@ -225,13 +237,21 @@ This implementation is explained more in the sidebar below::
225
237
public function getArguments(Request $request, $controller);
226
238
}
227
239
240
+ .. caution ::
241
+
242
+ The ``getArguments() `` method in the :class: `Symfony\\ Component\\ Httpkernel\\ Controller\\ ControllerResolver `
243
+ and respective interface :class: `Symfony\\ Component\\ Httpkernel\\ Controller\\ ControllerResolverInterface `
244
+ are deprecated as of 3.1 and will be removed in 4.0. You can use the
245
+ :class: `Symfony\\ Component\\ Httpkernel\\ Controller\\ ArgumentResolver ` which uses the
246
+ :class: `Symfony\\ Component\\ Httpkernel\\ Controller\\ ArgumentResolverInterface ` instead.
247
+
228
248
Internally, the ``HttpKernel::handle `` method first calls
229
249
:method: `Symfony\\ Component\\ HttpKernel\\ Controller\\ ControllerResolverInterface::getController `
230
250
on the controller resolver. This method is passed the ``Request `` and is responsible
231
251
for somehow determining and returning a PHP callable (the controller) based
232
252
on the request's information.
233
253
234
- The second method, :method: `Symfony\\ Component\\ HttpKernel\\ Controller\\ ControllerResolverInterface ::getArguments `,
254
+ The second method, :method: `Symfony\\ Component\\ HttpKernel\\ Controller\\ ArgumentResolverInterface ::getArguments `,
235
255
will be called after another event - ``kernel.controller `` - is dispatched.
236
256
237
257
.. sidebar :: Resolving the Controller in the Symfony Framework
@@ -310,11 +330,11 @@ on the event object that's passed to listeners on this event.
310
330
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
311
331
312
332
Next, ``HttpKernel::handle `` calls
313
- :method: `Symfony\\ Component\\ HttpKernel\\ Controller\\ ControllerResolverInterface ::getArguments `.
333
+ :method: `Symfony\\ Component\\ HttpKernel\\ Controller\\ ArgumentResolverInterface ::getArguments `.
314
334
Remember that the controller returned in ``getController `` is a callable.
315
335
The purpose of ``getArguments `` is to return the array of arguments that
316
336
should be passed to that controller. Exactly how this is done is completely
317
- up to your design, though the built-in :class: `Symfony\\ Component\\ HttpKernel\\ Controller\\ ControllerResolver `
337
+ up to your design, though the built-in :class: `Symfony\\ Component\\ HttpKernel\\ Controller\\ ArgumentResolver `
318
338
is a good example.
319
339
320
340
.. image :: /images/components/http_kernel/07-controller-arguments.png
@@ -326,7 +346,7 @@ of arguments that should be passed when executing that callable.
326
346
.. sidebar :: Getting the Controller Arguments in the Symfony Framework
327
347
328
348
Now that you know exactly what the controller callable (usually a method
329
- inside a controller object) is, the ``ControllerResolver `` uses `reflection `_
349
+ inside a controller object) is, the ``ArgumentResolver `` uses `reflection `_
330
350
on the callable to return an array of the *names * of each of the arguments.
331
351
It then iterates over each of these arguments and uses the following tricks
332
352
to determine which value should be passed for each argument:
@@ -338,8 +358,19 @@ of arguments that should be passed when executing that callable.
338
358
from the ``RouterListener ``).
339
359
340
360
b) If the argument in the controller is type-hinted with Symfony's
341
- :class: `Symfony\\ Component\\ HttpFoundation\\ Request ` object, then the
342
- ``Request `` is passed in as the value.
361
+ :class: `Symfony\\ Component\\ HttpFoundation\\ Request ` object, the
362
+ ``Request `` is passed in as the value. If you have a custom ``Request ``
363
+ class, it will be injected as long as you extend the Symfony ``Request ``.
364
+
365
+ c) If the function or method argument is `variadic `_ and the ``Request ``
366
+ ``attributes `` bag contains and array for that argument, they will all be
367
+ available through the `variadic `_ argument.
368
+
369
+ This functionality is provided by resolvers implementing the
370
+ :class: `Symfony\\ Component\\ HttpKernel\\ Controller\\ ArgumentValueResolverInterface `.
371
+ There are four implementations which provide the default behavior of Symfony but
372
+ customization is the key here. By implementing the ``ArgumentValueResolverInterface ``
373
+ yourself and passing this to the ``ArgumentResolver ``, you can extend this functionality.
343
374
344
375
.. _component-http-kernel-calling-controller :
345
376
@@ -612,47 +643,52 @@ A full Working Example
612
643
----------------------
613
644
614
645
When using the HttpKernel component, you're free to attach any listeners
615
- to the core events and use any controller resolver that implements the
616
- :class: `Symfony\\ Component\\ HttpKernel\\ Controller\\ ControllerResolverInterface `.
617
- However, the HttpKernel component comes with some built-in listeners and
618
- a built-in ControllerResolver that can be used to create a working example::
646
+ to the core events, use any controller resolver that implements the
647
+ :class: `Symfony\\ Component\\ HttpKernel\\ Controller\\ ControllerResolverInterface ` and
648
+ use any argument resolver that implements the
649
+ :class: `Symfony\\ Component\\ HttpKernel\\ Controller\\ ArgumentResolverInterface `.
650
+ However, the HttpKernel component comes with some built-in listeners and everything
651
+ else that can be used to create a working example::
619
652
620
- use Symfony\Component\HttpFoundation\Request;
621
- use Symfony\Component\HttpFoundation\RequestStack;
622
- use Symfony\Component\HttpFoundation\Response;
623
- use Symfony\Component\HttpKernel\HttpKernel;
624
- use Symfony\Component\EventDispatcher\EventDispatcher;
625
- use Symfony\Component\HttpKernel\Controller\ControllerResolver;
626
- use Symfony\Component\HttpKernel\EventListener\RouterListener;
627
- use Symfony\Component\Routing\RouteCollection;
628
- use Symfony\Component\Routing\Route;
629
- use Symfony\Component\Routing\Matcher\UrlMatcher;
630
- use Symfony\Component\Routing\RequestContext;
631
-
632
- $routes = new RouteCollection();
633
- $routes->add('hello', new Route('/hello/{name}', array(
634
- '_controller' => function (Request $request) {
635
- return new Response(
636
- sprintf("Hello %s", $request->get('name'))
637
- );
638
- }
639
- )
640
- ));
653
+ use Symfony\Component\EventDispatcher\EventDispatcher;
654
+ use Symfony\Component\HttpFoundation\Request;
655
+ use Symfony\Component\HttpFoundation\RequestStack;
656
+ use Symfony\Component\HttpFoundation\Response;
657
+ use Symfony\Component\HttpKernel\Controller\ArgumentResolver;
658
+ use Symfony\Component\HttpKernel\Controller\ControllerResolver;
659
+ use Symfony\Component\HttpKernel\EventListener\RouterListener;
660
+ use Symfony\Component\HttpKernel\HttpKernel;
661
+ use Symfony\Component\Routing\Matcher\UrlMatcher;
662
+ use Symfony\Component\Routing\RequestContext;
663
+ use Symfony\Component\Routing\Route;
664
+ use Symfony\Component\Routing\RouteCollection;
641
665
642
- $request = Request::createFromGlobals();
666
+ $routes = new RouteCollection();
667
+ $routes->add('hello', new Route('/hello/{name}', array(
668
+ '_controller' => function (Request $request) {
669
+ return new Response(
670
+ sprintf("Hello %s", $request->get('name'))
671
+ );
672
+ })
673
+ ));
643
674
644
- $matcher = new UrlMatcher($routes, new RequestContext() );
675
+ $request = Request::createFromGlobals( );
645
676
646
- $dispatcher = new EventDispatcher();
647
- $dispatcher->addSubscriber(new RouterListener($matcher, new RequestStack()));
677
+ $matcher = new UrlMatcher($routes, new RequestContext());
648
678
649
- $resolver = new ControllerResolver ();
650
- $kernel = new HttpKernel($dispatcher, $resolver );
679
+ $dispatcher = new EventDispatcher ();
680
+ $dispatcher->addSubscriber( new RouterListener($matcher, new RequestStack()) );
651
681
652
- $response = $kernel->handle($request);
653
- $response->send();
682
+ $controllerResolver = new ControllerResolver();
683
+ $argumentResolver = new ArgumentResolver();
684
+
685
+ $kernel = new HttpKernel($dispatcher, $controllerResolver, new RequestStack(), $argumentResolver);
686
+
687
+ $response = $kernel->handle($request);
688
+ $response->send();
689
+
690
+ $kernel->terminate($request, $response);
654
691
655
- $kernel->terminate($request, $response);
656
692
657
693
.. _http-kernel-sub-requests :
658
694
@@ -716,3 +752,4 @@ look like this::
716
752
.. _`@ParamConverter` : https://symfony.com/doc/current/bundles/SensioFrameworkExtraBundle/annotations/converters.html
717
753
.. _`@Template` : https://symfony.com/doc/current/bundles/SensioFrameworkExtraBundle/annotations/view.html
718
754
.. _`EmailSenderListener` : https://github.com/symfony/swiftmailer-bundle/blob/master/EventListener/EmailSenderListener.php
755
+ .. _variadic : http://php.net/manual/en/functions.arguments.php
0 commit comments