@@ -85,11 +85,22 @@ is really simple and involves creating an
85
85
:doc: `event dispatcher </components/event_dispatcher/introduction >` and a
86
86
:ref: `controller resolver <component-http-kernel-resolve-controller >` (explained
87
87
below). To complete your working kernel, you'll add more event listeners
88
- to the events discussed below::
88
+ to the events discussed below
89
+
90
+ .. caution ::
91
+
92
+ As of 3.1 the :class: `Symfony\\ Component\\ Httpkernel\\ HttpKernel ` accepts a fourth argument, which
93
+ should be an instance of :class: `Symfony\\ Component\\ Httpkernel\\ Controller\\ ArgumentResolverInterface `.
94
+ In 4.0 this argument will become mandatory and the :class: `Symfony\\ Component\\ Httpkernel\\ HttpKernel `
95
+ will no longer be able to fall back to the :class: `Symfony\\ Component\\ Httpkernel\\ Controller\\ ControllerResolver `.
96
+
97
+ .. code-block :: php
89
98
90
99
use Symfony\Component\HttpFoundation\Request;
91
100
use Symfony\Component\HttpKernel\HttpKernel;
92
101
use Symfony\Component\EventDispatcher\EventDispatcher;
102
+ use Symfony\Component\HttpFoundation\RequestStack;
103
+ use Symfony\Component\HttpKernel\Controller\ArgumentResolver;
93
104
use Symfony\Component\HttpKernel\Controller\ControllerResolver;
94
105
95
106
// create the Request object
@@ -98,10 +109,12 @@ to the events discussed below::
98
109
$dispatcher = new EventDispatcher();
99
110
// ... add some event listeners
100
111
101
- // create your controller resolver
102
- $resolver = new ControllerResolver();
112
+ // create your controller and argument resolvers
113
+ $controllerResolver = new ControllerResolver();
114
+ $argumentResolver = new ArgumentResolver();
115
+
103
116
// instantiate the kernel
104
- $kernel = new HttpKernel($dispatcher, $resolver );
117
+ $kernel = new HttpKernel($dispatcher, $controllerResolver, new RequestStack(), $argumentResolver );
105
118
106
119
// actually execute the kernel, which turns the request into a response
107
120
// by dispatching events, calling a controller, and returning the response
@@ -212,7 +225,19 @@ Your job is to create a class that implements the interface and fill in its
212
225
two methods: ``getController `` and ``getArguments ``. In fact, one default
213
226
implementation already exists, which you can use directly or learn from:
214
227
:class: `Symfony\\ Component\\ HttpKernel\\ Controller\\ ControllerResolver `.
215
- This implementation is explained more in the sidebar below::
228
+ This implementation is explained more in the sidebar below
229
+
230
+
231
+ .. caution ::
232
+
233
+ The `getArguments() ` method in the :class: `Symfony\\ Component\\ Httpkernel\\ Controller\\ ControllerResolver `
234
+ and respective interface :class: `Symfony\\ Component\\ Httpkernel\\ Controller\\ ControllerResolverInterface `
235
+ are deprecated as of 3.1 and will be removed in 4.0. You can use the
236
+ :class: `Symfony\\ Component\\ Httpkernel\\ Controller\\ ArgumentResolver ` which uses the
237
+ :class: `Symfony\\ Component\\ Httpkernel\\ Controller\\ ArgumentResolverInterface ` instead.
238
+
239
+
240
+ .. code-block :: php
216
241
217
242
namespace Symfony\Component\HttpKernel\Controller;
218
243
@@ -231,7 +256,7 @@ on the controller resolver. This method is passed the ``Request`` and is respons
231
256
for somehow determining and returning a PHP callable (the controller) based
232
257
on the request's information.
233
258
234
- The second method, :method: `Symfony\\ Component\\ HttpKernel\\ Controller\\ ControllerResolverInterface ::getArguments `,
259
+ The second method, :method: `Symfony\\ Component\\ HttpKernel\\ Controller\\ ArgumentResolverInterface ::getArguments `,
235
260
will be called after another event - ``kernel.controller `` - is dispatched.
236
261
237
262
.. sidebar :: Resolving the Controller in the Symfony Framework
@@ -310,11 +335,11 @@ on the event object that's passed to listeners on this event.
310
335
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
311
336
312
337
Next, ``HttpKernel::handle `` calls
313
- :method: `Symfony\\ Component\\ HttpKernel\\ Controller\\ ControllerResolverInterface ::getArguments `.
338
+ :method: `Symfony\\ Component\\ HttpKernel\\ Controller\\ ArgumentResolverInterface ::getArguments `.
314
339
Remember that the controller returned in ``getController `` is a callable.
315
340
The purpose of ``getArguments `` is to return the array of arguments that
316
341
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 `
342
+ up to your design, though the built-in :class: `Symfony\\ Component\\ HttpKernel\\ Controller\\ ArgumentResolver `
318
343
is a good example.
319
344
320
345
.. image :: /images/components/http_kernel/07-controller-arguments.png
@@ -326,7 +351,7 @@ of arguments that should be passed when executing that callable.
326
351
.. sidebar :: Getting the Controller Arguments in the Symfony Framework
327
352
328
353
Now that you know exactly what the controller callable (usually a method
329
- inside a controller object) is, the ``ControllerResolver `` uses `reflection `_
354
+ inside a controller object) is, the ``ArgumentResolver `` uses `reflection `_
330
355
on the callable to return an array of the *names * of each of the arguments.
331
356
It then iterates over each of these arguments and uses the following tricks
332
357
to determine which value should be passed for each argument:
@@ -339,7 +364,18 @@ of arguments that should be passed when executing that callable.
339
364
340
365
b) If the argument in the controller is type-hinted with Symfony's
341
366
:class: `Symfony\\ Component\\ HttpFoundation\\ Request ` object, then the
342
- ``Request `` is passed in as the value.
367
+ ``Request `` is passed in as the value. If you have a custom class extending
368
+ the ``Request ``, this is also accepted.
369
+
370
+ c) If the function or method argument is `variadic `_ and the ``Request ``
371
+ ``attributes `` bag contains and array for that argument, they will all be
372
+ available through the `variadic `_ argument.
373
+
374
+ This functionality is provided by resolvers implementing the
375
+ :class: `Symfony\\ Component\\ HttpKernel\\ Controller\\ ArgumentValueResolverInterface `.
376
+ There are four implementations which provide the default behavior of Symfony but
377
+ customization is the key here. By implementing the ``ArgumentValueResolverInterface ``
378
+ yourself and passing this to the ``ArgumentResolver ``, you can extend this functionality.
343
379
344
380
.. _component-http-kernel-calling-controller :
345
381
@@ -612,47 +648,52 @@ A full Working Example
612
648
----------------------
613
649
614
650
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::
651
+ to the core events, use any controller resolver that implements the
652
+ :class: `Symfony\\ Component\\ HttpKernel\\ Controller\\ ControllerResolverInterface ` and
653
+ use any argument resolver that implements the
654
+ :class: `Symfony\\ Component\\ HttpKernel\\ Controller\\ ArgumentResolverInterface `.
655
+ However, the HttpKernel component comes with some built-in listeners, and everything
656
+ else that can be used to create a working example::
619
657
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
- ));
658
+ use Symfony\Component\EventDispatcher\EventDispatcher;
659
+ use Symfony\Component\HttpFoundation\Request;
660
+ use Symfony\Component\HttpFoundation\RequestStack;
661
+ use Symfony\Component\HttpFoundation\Response;
662
+ use Symfony\Component\HttpKernel\Controller\ArgumentResolver;
663
+ use Symfony\Component\HttpKernel\Controller\ControllerResolver;
664
+ use Symfony\Component\HttpKernel\EventListener\RouterListener;
665
+ use Symfony\Component\HttpKernel\HttpKernel;
666
+ use Symfony\Component\Routing\Matcher\UrlMatcher;
667
+ use Symfony\Component\Routing\RequestContext;
668
+ use Symfony\Component\Routing\Route;
669
+ use Symfony\Component\Routing\RouteCollection;
641
670
642
- $request = Request::createFromGlobals();
671
+ $routes = new RouteCollection();
672
+ $routes->add('hello', new Route('/hello/{name}', array(
673
+ '_controller' => function (Request $request) {
674
+ return new Response(
675
+ sprintf("Hello %s", $request->get('name'))
676
+ );
677
+ })
678
+ ));
643
679
644
- $matcher = new UrlMatcher($routes, new RequestContext() );
680
+ $request = Request::createFromGlobals( );
645
681
646
- $dispatcher = new EventDispatcher();
647
- $dispatcher->addSubscriber(new RouterListener($matcher, new RequestStack()));
682
+ $matcher = new UrlMatcher($routes, new RequestContext());
648
683
649
- $resolver = new ControllerResolver ();
650
- $kernel = new HttpKernel($dispatcher, $resolver );
684
+ $dispatcher = new EventDispatcher ();
685
+ $dispatcher->addSubscriber( new RouterListener($matcher, new RequestStack()) );
651
686
652
- $response = $kernel->handle($request);
653
- $response->send();
687
+ $controllerResolver = new ControllerResolver();
688
+ $argumentResolver = new ArgumentResolver();
689
+
690
+ $kernel = new HttpKernel($dispatcher, $controllerResolver, new RequestStack(), $argumentResolver);
691
+
692
+ $response = $kernel->handle($request);
693
+ $response->send();
694
+
695
+ $kernel->terminate($request, $response);
654
696
655
- $kernel->terminate($request, $response);
656
697
657
698
.. _http-kernel-sub-requests :
658
699
@@ -716,3 +757,4 @@ look like this::
716
757
.. _`@ParamConverter` : https://symfony.com/doc/current/bundles/SensioFrameworkExtraBundle/annotations/converters.html
717
758
.. _`@Template` : https://symfony.com/doc/current/bundles/SensioFrameworkExtraBundle/annotations/view.html
718
759
.. _`EmailSenderListener` : https://github.com/symfony/swiftmailer-bundle/blob/master/EventListener/EmailSenderListener.php
760
+ .. _variadic : http://php.net/manual/en/functions.arguments.php
0 commit comments