diff --git a/components/http_kernel/introduction.rst b/components/http_kernel/introduction.rst index 2e2ae670da0..5b1acf99050 100644 --- a/components/http_kernel/introduction.rst +++ b/components/http_kernel/introduction.rst @@ -90,6 +90,8 @@ to the events discussed below:: use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpKernel\HttpKernel; use Symfony\Component\EventDispatcher\EventDispatcher; + use Symfony\Component\HttpFoundation\RequestStack; + use Symfony\Component\HttpKernel\Controller\ArgumentResolver; use Symfony\Component\HttpKernel\Controller\ControllerResolver; // create the Request object @@ -98,10 +100,12 @@ to the events discussed below:: $dispatcher = new EventDispatcher(); // ... add some event listeners - // create your controller resolver - $resolver = new ControllerResolver(); + // create your controller and argument resolvers + $controllerResolver = new ControllerResolver(); + $argumentResolver = new ArgumentResolver(); + // instantiate the kernel - $kernel = new HttpKernel($dispatcher, $resolver); + $kernel = new HttpKernel($dispatcher, $controllerResolver, new RequestStack(), $argumentResolver); // actually execute the kernel, which turns the request into a response // 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. For general information on adding listeners to the events below, see :ref:`http-kernel-creating-listener`. + +.. caution:: + + As of 3.1 the :class:`Symfony\\Component\\Httpkernel\\HttpKernel` accepts a fourth argument, which + must be an instance of :class:`Symfony\\Component\\Httpkernel\\Controller\\ArgumentResolverInterface`. + In 4.0 this argument will become mandatory and the :class:`Symfony\\Component\\Httpkernel\\HttpKernel` + will no longer be able to fall back to the :class:`Symfony\\Component\\Httpkernel\\Controller\\ControllerResolver`. + .. seealso:: 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:: public function getArguments(Request $request, $controller); } +.. caution:: + + The ``getArguments()`` method in the :class:`Symfony\\Component\\Httpkernel\\Controller\\ControllerResolver` + and respective interface :class:`Symfony\\Component\\Httpkernel\\Controller\\ControllerResolverInterface` + are deprecated as of 3.1 and will be removed in 4.0. You can use the + :class:`Symfony\\Component\\Httpkernel\\Controller\\ArgumentResolver` which uses the + :class:`Symfony\\Component\\Httpkernel\\Controller\\ArgumentResolverInterface` instead. + Internally, the ``HttpKernel::handle`` method first calls :method:`Symfony\\Component\\HttpKernel\\Controller\\ControllerResolverInterface::getController` on the controller resolver. This method is passed the ``Request`` and is responsible for somehow determining and returning a PHP callable (the controller) based on the request's information. -The second method, :method:`Symfony\\Component\\HttpKernel\\Controller\\ControllerResolverInterface::getArguments`, +The second method, :method:`Symfony\\Component\\HttpKernel\\Controller\\ArgumentResolverInterface::getArguments`, will be called after another event - ``kernel.controller`` - is dispatched. .. sidebar:: Resolving the Controller in the Symfony Framework @@ -310,11 +330,11 @@ on the event object that's passed to listeners on this event. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Next, ``HttpKernel::handle`` calls -:method:`Symfony\\Component\\HttpKernel\\Controller\\ControllerResolverInterface::getArguments`. +:method:`Symfony\\Component\\HttpKernel\\Controller\\ArgumentResolverInterface::getArguments`. Remember that the controller returned in ``getController`` is a callable. The purpose of ``getArguments`` is to return the array of arguments that should be passed to that controller. Exactly how this is done is completely -up to your design, though the built-in :class:`Symfony\\Component\\HttpKernel\\Controller\\ControllerResolver` +up to your design, though the built-in :class:`Symfony\\Component\\HttpKernel\\Controller\\ArgumentResolver` is a good example. .. image:: /images/components/http_kernel/07-controller-arguments.png @@ -326,7 +346,7 @@ of arguments that should be passed when executing that callable. .. sidebar:: Getting the Controller Arguments in the Symfony Framework Now that you know exactly what the controller callable (usually a method - inside a controller object) is, the ``ControllerResolver`` uses `reflection`_ + inside a controller object) is, the ``ArgumentResolver`` uses `reflection`_ on the callable to return an array of the *names* of each of the arguments. It then iterates over each of these arguments and uses the following tricks to determine which value should be passed for each argument: @@ -338,8 +358,19 @@ of arguments that should be passed when executing that callable. from the ``RouterListener``). b) If the argument in the controller is type-hinted with Symfony's - :class:`Symfony\\Component\\HttpFoundation\\Request` object, then the - ``Request`` is passed in as the value. + :class:`Symfony\\Component\\HttpFoundation\\Request` object, the + ``Request`` is passed in as the value. If you have a custom ``Request`` + class, it will be injected as long as you extend the Symfony ``Request``. + + c) If the function or method argument is `variadic`_ and the ``Request`` + ``attributes`` bag contains and array for that argument, they will all be + available through the `variadic`_ argument. + + This functionality is provided by resolvers implementing the + :class:`Symfony\\Component\\HttpKernel\\Controller\\ArgumentValueResolverInterface`. + There are four implementations which provide the default behavior of Symfony but + customization is the key here. By implementing the ``ArgumentValueResolverInterface`` + yourself and passing this to the ``ArgumentResolver``, you can extend this functionality. .. _component-http-kernel-calling-controller: @@ -612,47 +643,52 @@ A full Working Example ---------------------- When using the HttpKernel component, you're free to attach any listeners -to the core events and use any controller resolver that implements the -:class:`Symfony\\Component\\HttpKernel\\Controller\\ControllerResolverInterface`. -However, the HttpKernel component comes with some built-in listeners and -a built-in ControllerResolver that can be used to create a working example:: +to the core events, use any controller resolver that implements the +:class:`Symfony\\Component\\HttpKernel\\Controller\\ControllerResolverInterface` and +use any argument resolver that implements the +:class:`Symfony\\Component\\HttpKernel\\Controller\\ArgumentResolverInterface`. +However, the HttpKernel component comes with some built-in listeners and everything +else that can be used to create a working example:: - use Symfony\Component\HttpFoundation\Request; - use Symfony\Component\HttpFoundation\RequestStack; - use Symfony\Component\HttpFoundation\Response; - use Symfony\Component\HttpKernel\HttpKernel; - use Symfony\Component\EventDispatcher\EventDispatcher; - use Symfony\Component\HttpKernel\Controller\ControllerResolver; - use Symfony\Component\HttpKernel\EventListener\RouterListener; - use Symfony\Component\Routing\RouteCollection; - use Symfony\Component\Routing\Route; - use Symfony\Component\Routing\Matcher\UrlMatcher; - use Symfony\Component\Routing\RequestContext; - - $routes = new RouteCollection(); - $routes->add('hello', new Route('/hello/{name}', array( - '_controller' => function (Request $request) { - return new Response( - sprintf("Hello %s", $request->get('name')) - ); - } - ) - )); + use Symfony\Component\EventDispatcher\EventDispatcher; + use Symfony\Component\HttpFoundation\Request; + use Symfony\Component\HttpFoundation\RequestStack; + use Symfony\Component\HttpFoundation\Response; + use Symfony\Component\HttpKernel\Controller\ArgumentResolver; + use Symfony\Component\HttpKernel\Controller\ControllerResolver; + use Symfony\Component\HttpKernel\EventListener\RouterListener; + use Symfony\Component\HttpKernel\HttpKernel; + use Symfony\Component\Routing\Matcher\UrlMatcher; + use Symfony\Component\Routing\RequestContext; + use Symfony\Component\Routing\Route; + use Symfony\Component\Routing\RouteCollection; - $request = Request::createFromGlobals(); + $routes = new RouteCollection(); + $routes->add('hello', new Route('/hello/{name}', array( + '_controller' => function (Request $request) { + return new Response( + sprintf("Hello %s", $request->get('name')) + ); + }) + )); - $matcher = new UrlMatcher($routes, new RequestContext()); + $request = Request::createFromGlobals(); - $dispatcher = new EventDispatcher(); - $dispatcher->addSubscriber(new RouterListener($matcher, new RequestStack())); + $matcher = new UrlMatcher($routes, new RequestContext()); - $resolver = new ControllerResolver(); - $kernel = new HttpKernel($dispatcher, $resolver); + $dispatcher = new EventDispatcher(); + $dispatcher->addSubscriber(new RouterListener($matcher, new RequestStack())); - $response = $kernel->handle($request); - $response->send(); + $controllerResolver = new ControllerResolver(); + $argumentResolver = new ArgumentResolver(); + + $kernel = new HttpKernel($dispatcher, $controllerResolver, new RequestStack(), $argumentResolver); + + $response = $kernel->handle($request); + $response->send(); + + $kernel->terminate($request, $response); - $kernel->terminate($request, $response); .. _http-kernel-sub-requests: @@ -716,3 +752,4 @@ look like this:: .. _`@ParamConverter`: https://symfony.com/doc/current/bundles/SensioFrameworkExtraBundle/annotations/converters.html .. _`@Template`: https://symfony.com/doc/current/bundles/SensioFrameworkExtraBundle/annotations/view.html .. _`EmailSenderListener`: https://github.com/symfony/swiftmailer-bundle/blob/master/EventListener/EmailSenderListener.php +.. _variadic: http://php.net/manual/en/functions.arguments.php diff --git a/create_framework/dependency_injection.rst b/create_framework/dependency_injection.rst index 36fa99ffd84..691d5f7a61d 100644 --- a/create_framework/dependency_injection.rst +++ b/create_framework/dependency_injection.rst @@ -9,9 +9,10 @@ to it:: // example.com/src/Simplex/Framework.php namespace Simplex; + use Symfony\Component\EventDispatcher\EventDispatcher; use Symfony\Component\Routing; + use Symfony\Component\HttpFoundation; use Symfony\Component\HttpKernel; - use Symfony\Component\EventDispatcher\EventDispatcher; class Framework extends HttpKernel\HttpKernel { @@ -19,13 +20,15 @@ to it:: { $context = new Routing\RequestContext(); $matcher = new Routing\Matcher\UrlMatcher($routes, $context); - $resolver = new HttpKernel\Controller\ControllerResolver(); + + $controllerResolver = new HttpKernel\Controller\ControllerResolver(); + $argumentResolver = new HttpKernel\Controller\ArgumentResolver(); $dispatcher = new EventDispatcher(); $dispatcher->addSubscriber(new HttpKernel\EventListener\RouterListener($matcher)); $dispatcher->addSubscriber(new HttpKernel\EventListener\ResponseListener('UTF-8')); - parent::__construct($dispatcher, $resolver); + parent::__construct($dispatcher, $controllerResolver, new RequestStack(), $argumentResolver); } } @@ -101,7 +104,8 @@ Create a new file to host the dependency injection container configuration:: ->setArguments(array($routes, new Reference('context'))) ; $sc->register('request_stack', 'Symfony\Component\HttpFoundation\RequestStack'); - $sc->register('resolver', 'Symfony\Component\HttpKernel\Controller\ControllerResolver'); + $sc->register('controller_resolver', 'Symfony\Component\HttpKernel\Controller\ControllerResolver'); + $sc->register('argument_resolver', 'Symfony\Component\HttpKernel\Controller\ArgumentResolver'); $sc->register('listener.router', 'Symfony\Component\HttpKernel\EventListener\RouterListener') ->setArguments(array(new Reference('matcher'), new Reference('request_stack'))) @@ -118,7 +122,12 @@ Create a new file to host the dependency injection container configuration:: ->addMethodCall('addSubscriber', array(new Reference('listener.exception'))) ; $sc->register('framework', 'Simplex\Framework') - ->setArguments(array(new Reference('dispatcher'), new Reference('resolver'))) + ->setArguments(array( + new Reference('dispatcher'), + new Reference('controller_resolver'), + new Reference('request_stack'), + new Reference('argument_resolver'), + )) ; return $sc; diff --git a/create_framework/event_dispatcher.rst b/create_framework/event_dispatcher.rst index 3964cf5ae46..679359c620a 100644 --- a/create_framework/event_dispatcher.rst +++ b/create_framework/event_dispatcher.rst @@ -36,24 +36,27 @@ the Response instance:: // example.com/src/Simplex/Framework.php namespace Simplex; + use Symfony\Component\EventDispatcher\EventDispatcher; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; - use Symfony\Component\Routing\Matcher\UrlMatcherInterface; - use Symfony\Component\Routing\Exception\ResourceNotFoundException; + use Symfony\Component\HttpKernel\Controller\ArgumentResolverInterface; use Symfony\Component\HttpKernel\Controller\ControllerResolverInterface; - use Symfony\Component\EventDispatcher\EventDispatcher; + use Symfony\Component\Routing\Exception\ResourceNotFoundException; + use Symfony\Component\Routing\Matcher\UrlMatcherInterface; class Framework { - private $matcher; - private $resolver; private $dispatcher; + private $matcher; + private $controllerResolver; + private $argumentResolver; - public function __construct(EventDispatcher $dispatcher, UrlMatcherInterface $matcher, ControllerResolverInterface $resolver) + public function __construct(EventDispatcher $dispatcher, UrlMatcherInterface $matcher, ControllerResolverInterface $controllerResolver, ArgumentResolverInterface $argumentResolver) { - $this->matcher = $matcher; - $this->resolver = $resolver; $this->dispatcher = $dispatcher; + $this->matcher = $matcher; + $this->controllerResolver = $controllerResolver; + $this->argumentResolver = $argumentResolver; } public function handle(Request $request) @@ -63,8 +66,8 @@ the Response instance:: try { $request->attributes->add($this->matcher->match($request->getPathInfo())); - $controller = $this->resolver->getController($request); - $arguments = $this->resolver->getArguments($request, $controller); + $controller = $this->controllerResolver->getController($request); + $arguments = $this->argumentResolver->getArguments($request, $controller); $response = call_user_func_array($controller, $arguments); } catch (ResourceNotFoundException $e) { diff --git a/create_framework/http_kernel_controller_resolver.rst b/create_framework/http_kernel_controller_resolver.rst index c0cf260cf0b..147395bb88a 100644 --- a/create_framework/http_kernel_controller_resolver.rst +++ b/create_framework/http_kernel_controller_resolver.rst @@ -43,10 +43,10 @@ component: $ composer require symfony/http-kernel -The HttpKernel component has many interesting features, but the one we need -right now is the *controller resolver*. A controller resolver knows how to -determine the controller to execute and the arguments to pass to it, based on -a Request object. All controller resolvers implement the following interface:: +The HttpKernel component has many interesting features, but the ones we need +right now are the *controller resolver* and *argument resolver*. A controller resolver knows how to +determine the controller to execute and the argument resolver determines the arguments to pass to it, +based on a Request object. All controller resolvers implement the following interface:: namespace Symfony\Component\HttpKernel\Controller; @@ -58,6 +58,14 @@ a Request object. All controller resolvers implement the following interface:: function getArguments(Request $request, $controller); } +.. caution:: + + The ``getArguments()`` method in the :class:`Symfony\\Component\\Httpkernel\\Controller\\ControllerResolver` + and respective interface :class:`Symfony\\Component\\Httpkernel\\Controller\\ControllerResolverInterface` + are deprecated as of 3.1 and will be removed in 4.0. You can use the + :class:`Symfony\\Component\\Httpkernel\\Controller\\ArgumentResolver` which uses the + :class:`Symfony\\Component\\Httpkernel\\Controller\\ArgumentResolverInterface` instead. + The ``getController()`` method relies on the same convention as the one we have defined earlier: the ``_controller`` request attribute must contain the controller associated with the Request. Besides the built-in PHP callbacks, @@ -74,10 +82,11 @@ resolver from HttpKernel:: use Symfony\Component\HttpKernel; - $resolver = new HttpKernel\Controller\ControllerResolver(); + $controllerResolver = new HttpKernel\Controller\ControllerResolver(); + $argumentResolver = new HttpKernel\Controller\ArgumentResolver(); - $controller = $resolver->getController($request); - $arguments = $resolver->getArguments($request, $controller); + $controller = $controllerResolver->getController($request); + $arguments = $argumentResolver->getArguments($request, $controller); $response = call_user_func_array($controller, $arguments); @@ -140,14 +149,12 @@ method is not defined, an argument has no matching attribute, ...). .. note:: - With the great flexibility of the default controller resolver, you might - wonder why someone would want to create another one (why would there be an - interface if not?). Two examples: in Symfony, ``getController()`` is - enhanced to support - :doc:`controllers as services `; and in - `FrameworkExtraBundle`_, ``getArguments()`` is enhanced to support - parameter converters, where request attributes are converted to objects - automatically. + With the great flexibility of the default controller resolver and argument + resolver, you might wonder why someone would want to create another one + (why would there be an interface if not?). Two examples: in Symfony, + ``getController()`` is enhanced to support :doc:`controllers as services `; + and ``getArguments()`` provides an extension point to alter or enhance + the resolving of arguments. Let's conclude with the new version of our framework:: @@ -174,13 +181,18 @@ Let's conclude with the new version of our framework:: $context = new Routing\RequestContext(); $context->fromRequest($request); $matcher = new Routing\Matcher\UrlMatcher($routes, $context); - $resolver = new HttpKernel\Controller\ControllerResolver(); + + $controllerResolver = new HttpKernel\Controller\ControllerResolver(); + $argumentResolver = new HttpKernel\Controller\ArgumentResolver(); + + $controller = $controllerResolver->getController($request); + $arguments = $argumentResolver->getArguments($request, $controller); try { $request->attributes->add($matcher->match($request->getPathInfo())); - $controller = $resolver->getController($request); - $arguments = $resolver->getArguments($request, $controller); + $controller = $controllerResolver->getController($request); + $arguments = $argumentResolver->getArguments($request, $controller); $response = call_user_func_array($controller, $arguments); } catch (Routing\Exception\ResourceNotFoundException $e) { @@ -192,7 +204,7 @@ Let's conclude with the new version of our framework:: $response->send(); Think about it once more: our framework is more robust and more flexible than -ever and it still has less than 40 lines of code. +ever and it still has less than 50 lines of code. .. _`reflection`: http://php.net/reflection .. _`FrameworkExtraBundle`: http://symfony.com/doc/current/bundles/SensioFrameworkExtraBundle/annotations/converters.html diff --git a/create_framework/http_kernel_httpkernel_class.rst b/create_framework/http_kernel_httpkernel_class.rst index 5b4aba5556b..890369979d1 100644 --- a/create_framework/http_kernel_httpkernel_class.rst +++ b/create_framework/http_kernel_httpkernel_class.rst @@ -36,24 +36,27 @@ And the new front controller:: // example.com/web/front.php require_once __DIR__.'/../vendor/autoload.php'; + use Symfony\Component\EventDispatcher\EventDispatcher; use Symfony\Component\HttpFoundation\Request; + use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\HttpFoundation\Response; - use Symfony\Component\Routing; use Symfony\Component\HttpKernel; - use Symfony\Component\EventDispatcher\EventDispatcher; - use Symfony\Component\HttpFoundation\RequestStack; + use Symfony\Component\Routing; $request = Request::createFromGlobals(); + $requestStack = new RequestStack(); $routes = include __DIR__.'/../src/app.php'; $context = new Routing\RequestContext(); $matcher = new Routing\Matcher\UrlMatcher($routes, $context); - $resolver = new HttpKernel\Controller\ControllerResolver(); + + $controllerResolver = new HttpKernel\Controller\ControllerResolver(); + $argumentResolver = new HttpKernel\Controller\ArgumentResolver(); $dispatcher = new EventDispatcher(); - $dispatcher->addSubscriber(new HttpKernel\EventListener\RouterListener($matcher, new RequestStack())); + $dispatcher->addSubscriber(new HttpKernel\EventListener\RouterListener($matcher, $requestStack)); - $framework = new Simplex\Framework($dispatcher, $resolver); + $framework = new Simplex\Framework($dispatcher, $controllerResolver, $requestStack, $argumentResolver); $response = $framework->handle($request); $response->send(); @@ -151,9 +154,8 @@ only if needed:: namespace Simplex; use Symfony\Component\EventDispatcher\EventSubscriberInterface; - use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent; - use Symfony\Component\HttpKernel\KernelEvents; + use Symfony\Component\HttpFoundation\Response; class StringResponseListener implements EventSubscriberInterface { @@ -168,7 +170,7 @@ only if needed:: public static function getSubscribedEvents() { - return array(KernelEvents::VIEW => 'onView'); + return array('kernel.view' => 'onView'); } } diff --git a/create_framework/separation_of_concerns.rst b/create_framework/separation_of_concerns.rst index 9340e3b6519..ee3fe283ef1 100644 --- a/create_framework/separation_of_concerns.rst +++ b/create_framework/separation_of_concerns.rst @@ -2,7 +2,7 @@ The Separation of Concerns ========================== One down-side of our framework right now is that we need to copy and paste the -code in ``front.php`` each time we create a new website. 40 lines of code is +code in ``front.php`` each time we create a new website. 60 lines of code is not that much, but it would be nice if we could wrap this code into a proper class. It would bring us better *reusability* and easier testing to name just a few benefits. @@ -20,19 +20,22 @@ request handling logic into its own ``Simplex\\Framework`` class:: use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; - use Symfony\Component\Routing\Matcher\UrlMatcher; - use Symfony\Component\Routing\Exception\ResourceNotFoundException; + use Symfony\Component\HttpKernel\Controller\ArgumentResolver; use Symfony\Component\HttpKernel\Controller\ControllerResolver; + use Symfony\Component\Routing\Exception\ResourceNotFoundException; + use Symfony\Component\Routing\Matcher\UrlMatcher; class Framework { protected $matcher; - protected $resolver; + protected $controllerResolver; + protected $argumentResolver; - public function __construct(UrlMatcher $matcher, ControllerResolver $resolver) + public function __construct(UrlMatcher $matcher, ControllerResolver $controllerResolver, ArgumentResolver $argumentResolver) { $this->matcher = $matcher; - $this->resolver = $resolver; + $this->controllerResolver = $controllerResolver; + $this->argumentResolver = $argumentResolver; } public function handle(Request $request) @@ -42,8 +45,8 @@ request handling logic into its own ``Simplex\\Framework`` class:: try { $request->attributes->add($this->matcher->match($request->getPathInfo())); - $controller = $this->resolver->getController($request); - $arguments = $this->resolver->getArguments($request, $controller); + $controller = $this->controllerResolver->getController($request); + $arguments = $this->argumentResolver->getArguments($request, $controller); return call_user_func_array($controller, $arguments); } catch (ResourceNotFoundException $e) { @@ -64,9 +67,11 @@ And update ``example.com/web/front.php`` accordingly:: $context = new Routing\RequestContext(); $matcher = new Routing\Matcher\UrlMatcher($routes, $context); - $resolver = new HttpKernel\Controller\ControllerResolver(); - $framework = new Simplex\Framework($matcher, $resolver); + $controllerResolver = new ControllerResolver(); + $argumentResolver = new ArgumentResolver(); + + $framework = new Simplex\Framework($matcher, $controllerResolver, new RequestStack(), $argumentResolver); $response = $framework->handle($request); $response->send(); @@ -142,7 +147,7 @@ To sum up, here is the new file layout: example.com ├── composer.json - ├── composer.lock + ├── composer.lock ├── src │ ├── app.php │ └── Simplex diff --git a/reference/dic_tags.rst b/reference/dic_tags.rst index 5a9fba64137..7db13cd1109 100644 --- a/reference/dic_tags.rst +++ b/reference/dic_tags.rst @@ -24,6 +24,7 @@ Tag Name Usage `assetic.templating.twig`_ Remove this service if Twig templating is disabled `auto_alias`_ Define aliases based on the value of container parameters `console.command`_ Add a command +`controller.argument_value_resolver`_ Register a value resolver for controller arguments such as ``Request`` `data_collector`_ Create a class that collects custom data for the profiler `doctrine.event_listener`_ Add a Doctrine event listener `doctrine.event_subscriber`_ Add a Doctrine event subscriber @@ -350,6 +351,15 @@ console.command For details on registering your own commands in the service container, read :ref:`the cookbook article`. +controller.argument_value_resolver +---------------------------------- + +**Purpose**: Register a value resolver for controller arguments such as ``Request`` + +Value resolvers implement the :class:`Symfony\\Component\\HttpKernel\\Controller\\ArgumentValueResolverInterface` +and are used to resolve argument values for controllers as described here: +:doc:`/cookbook/controller/argument_value_resolver`. + data_collector -------------- pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy