@@ -85,11 +85,22 @@ is really simple and involves creating an
8585:doc: `event dispatcher </components/event_dispatcher/introduction >` and a
8686:ref: `controller resolver <component-http-kernel-resolve-controller >` (explained
8787below). 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
8998
9099 use Symfony\Component\HttpFoundation\Request;
91100 use Symfony\Component\HttpKernel\HttpKernel;
92101 use Symfony\Component\EventDispatcher\EventDispatcher;
102+ use Symfony\Component\HttpFoundation\RequestStack;
103+ use Symfony\Component\HttpKernel\Controller\ArgumentResolver;
93104 use Symfony\Component\HttpKernel\Controller\ControllerResolver;
94105
95106 // create the Request object
@@ -98,10 +109,12 @@ to the events discussed below::
98109 $dispatcher = new EventDispatcher();
99110 // ... add some event listeners
100111
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+
103116 // instantiate the kernel
104- $kernel = new HttpKernel($dispatcher, $resolver );
117+ $kernel = new HttpKernel($dispatcher, $controllerResolver, new RequestStack(), $argumentResolver );
105118
106119 // actually execute the kernel, which turns the request into a response
107120 // 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
212225two methods: ``getController `` and ``getArguments ``. In fact, one default
213226implementation already exists, which you can use directly or learn from:
214227: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
216241
217242 namespace Symfony\Component\HttpKernel\Controller;
218243
@@ -231,7 +256,7 @@ on the controller resolver. This method is passed the ``Request`` and is respons
231256for somehow determining and returning a PHP callable (the controller) based
232257on the request's information.
233258
234- The second method,:method: `Symfony\\ Component\\ HttpKernel\\ Controller\\ ControllerResolverInterface ::getArguments `,
259+ The second method,:method: `Symfony\\ Component\\ HttpKernel\\ Controller\\ ArgumentResolverInterface ::getArguments `,
235260will be called after another event - ``kernel.controller `` - is dispatched.
236261
237262..sidebar ::Resolving the Controller in the Symfony Framework
@@ -310,11 +335,11 @@ on the event object that's passed to listeners on this event.
310335~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
311336
312337Next, ``HttpKernel::handle `` calls
313- :method: `Symfony\\ Component\\ HttpKernel\\ Controller\\ ControllerResolverInterface ::getArguments `.
338+ :method: `Symfony\\ Component\\ HttpKernel\\ Controller\\ ArgumentResolverInterface ::getArguments `.
314339Remember that the controller returned in ``getController `` is a callable.
315340The purpose of ``getArguments `` is to return the array of arguments that
316341should 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 `
318343is a good example.
319344
320345..image ::/images/components/http_kernel/07-controller-arguments.png
@@ -326,7 +351,7 @@ of arguments that should be passed when executing that callable.
326351..sidebar ::Getting the Controller Arguments in the Symfony Framework
327352
328353 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 `_
330355 on the callable to return an array of the *names * of each of the arguments.
331356 It then iterates over each of these arguments and uses the following tricks
332357 to determine which value should be passed for each argument:
@@ -339,7 +364,18 @@ of arguments that should be passed when executing that callable.
339364
340365 b) If the argument in the controller is type-hinted with Symfony's
341366: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.
343379
344380.. _component-http-kernel-calling-controller :
345381
@@ -612,47 +648,52 @@ A full Working Example
612648----------------------
613649
614650When 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::
619657
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;
641670
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+ ));
643679
644- $matcher =new UrlMatcher($routes, new RequestContext() );
680+ $request =Request::createFromGlobals( );
645681
646- $dispatcher = new EventDispatcher();
647- $dispatcher->addSubscriber(new RouterListener($matcher, new RequestStack()));
682+ $matcher = new UrlMatcher($routes, new RequestContext());
648683
649- $resolver = newControllerResolver ();
650- $kernel = newHttpKernel($dispatcher, $resolver );
684+ $dispatcher = newEventDispatcher ();
685+ $dispatcher->addSubscriber( newRouterListener($matcher, new RequestStack()) );
651686
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);
654696
655- $kernel->terminate($request, $response);
656697
657698.. _http-kernel-sub-requests :
658699
@@ -716,3 +757,4 @@ look like this::
716757.. _`@ParamConverter` :https://symfony.com/doc/current/bundles/SensioFrameworkExtraBundle/annotations/converters.html
717758.. _`@Template` :https://symfony.com/doc/current/bundles/SensioFrameworkExtraBundle/annotations/view.html
718759.. _`EmailSenderListener` :https://github.com/symfony/swiftmailer-bundle/blob/master/EventListener/EmailSenderListener.php
760+ .. _variadic :http://php.net/manual/en/functions.arguments.php