@@ -90,6 +90,8 @@ to the events discussed below::
9090 use Symfony\Component\HttpFoundation\Request;
9191 use Symfony\Component\HttpKernel\HttpKernel;
9292 use Symfony\Component\EventDispatcher\EventDispatcher;
93+ use Symfony\Component\HttpFoundation\RequestStack;
94+ use Symfony\Component\HttpKernel\Controller\ArgumentResolver;
9395 use Symfony\Component\HttpKernel\Controller\ControllerResolver;
9496
9597 // create the Request object
@@ -98,10 +100,12 @@ to the events discussed below::
98100 $dispatcher = new EventDispatcher();
99101 // ... add some event listeners
100102
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+
103107 // instantiate the kernel
104- $kernel = new HttpKernel($dispatcher, $resolver );
108+ $kernel = new HttpKernel($dispatcher, $controllerResolver, new RequestStack(), $argumentResolver );
105109
106110 // actually execute the kernel, which turns the request into a response
107111 // 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.
118122For general information on adding listeners to the events below, see
119123:ref: `http-kernel-creating-listener `.
120124
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+
121133..seealso ::
122134
123135 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::
225237 public function getArguments(Request $request, $controller);
226238 }
227239
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+
228248Internally, the ``HttpKernel::handle `` method first calls
229249:method: `Symfony\\ Component\\ HttpKernel\\ Controller\\ ControllerResolverInterface::getController `
230250on the controller resolver. This method is passed the ``Request `` and is responsible
231251for somehow determining and returning a PHP callable (the controller) based
232252on the request's information.
233253
234- The second method,:method: `Symfony\\ Component\\ HttpKernel\\ Controller\\ ControllerResolverInterface ::getArguments `,
254+ The second method,:method: `Symfony\\ Component\\ HttpKernel\\ Controller\\ ArgumentResolverInterface ::getArguments `,
235255will be called after another event - ``kernel.controller `` - is dispatched.
236256
237257..sidebar ::Resolving the Controller in the Symfony Framework
@@ -310,11 +330,11 @@ on the event object that's passed to listeners on this event.
310330~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
311331
312332Next, ``HttpKernel::handle `` calls
313- :method: `Symfony\\ Component\\ HttpKernel\\ Controller\\ ControllerResolverInterface ::getArguments `.
333+ :method: `Symfony\\ Component\\ HttpKernel\\ Controller\\ ArgumentResolverInterface ::getArguments `.
314334Remember that the controller returned in ``getController `` is a callable.
315335The purpose of ``getArguments `` is to return the array of arguments that
316336should 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 `
318338is a good example.
319339
320340..image ::/images/components/http_kernel/07-controller-arguments.png
@@ -326,7 +346,7 @@ of arguments that should be passed when executing that callable.
326346..sidebar ::Getting the Controller Arguments in the Symfony Framework
327347
328348 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 `_
330350 on the callable to return an array of the *names * of each of the arguments.
331351 It then iterates over each of these arguments and uses the following tricks
332352 to determine which value should be passed for each argument:
@@ -338,8 +358,19 @@ of arguments that should be passed when executing that callable.
338358 from the ``RouterListener ``).
339359
340360 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.
343374
344375.. _component-http-kernel-calling-controller :
345376
@@ -612,47 +643,52 @@ A full Working Example
612643----------------------
613644
614645When 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::
619652
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;
641665
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+ ));
643674
644- $matcher =new UrlMatcher($routes, new RequestContext() );
675+ $request =Request::createFromGlobals( );
645676
646- $dispatcher = new EventDispatcher();
647- $dispatcher->addSubscriber(new RouterListener($matcher, new RequestStack()));
677+ $matcher = new UrlMatcher($routes, new RequestContext());
648678
649- $resolver = newControllerResolver ();
650- $kernel = newHttpKernel($dispatcher, $resolver );
679+ $dispatcher = newEventDispatcher ();
680+ $dispatcher->addSubscriber( newRouterListener($matcher, new RequestStack()) );
651681
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);
654691
655- $kernel->terminate($request, $response);
656692
657693.. _http-kernel-sub-requests :
658694
@@ -716,3 +752,4 @@ look like this::
716752.. _`@ParamConverter` :https://symfony.com/doc/current/bundles/SensioFrameworkExtraBundle/annotations/converters.html
717753.. _`@Template` :https://symfony.com/doc/current/bundles/SensioFrameworkExtraBundle/annotations/view.html
718754.. _`EmailSenderListener` :https://github.com/symfony/swiftmailer-bundle/blob/master/EventListener/EmailSenderListener.php
755+ .. _variadic :http://php.net/manual/en/functions.arguments.php