Symfony 2.0, RequestHandler Component

    The Symfony Components website says about the RequestHandler component like this:
    Flexible micro-core for fast frameworks.

    Is this so and what is RequestHandler in Symfony 2 I'll try to consider in this topic.

    If we look at the process of processing a request in an application based on Symfony 2, namely, consider the run()class method Symfony\Foundation\Kernel, then we will see that after creating and storing in the cache or loading the DI container from the cache, we get the request handler object from the container and call its method handle()in the parameters, which the request object is transferred, by the way also obtained from the DI container. This method should return a response object whose method is calledsend()to send a response. In general, the first blow in processing the request is accepted by the RequestHandler, it also returns the response object, so I decided to start the review of the components included in Symfony 2 with it.

    First, let's take a look at Symfony/Foundation/Resources/services.xmlhow exactly here is the description of the RequestHandlerService service in the DI container.

    Symfony \ Components \ RequestHandler \ RequestHandlerSymfony \ components \ RequestHandler \ Response
    ...
    

    From this description, it becomes clear that the request object is created simply new Request(), and the request handler object, like new RequestHandler($dispatcher)where the $dispatcherobject of the EventDispatcher class, which is an event dispatcher.

    Having looked in Symfony / Components / RequestHandler we will see the following set of files:
    • Exception/: directory with exception classes
      • ForbiddenHttpException.php: exception thrown at 403 Forbidden
      • HttpException.php: base class for exceptions
      • NotFoundHttpException.php: throwing exception at 404 Not Found
      • UnauthorizedHttpException.php: an exception thrown at 401 Unauthorized

    • Request.php: request class
    • RequestInterface.php: the interface that the request object should implement
    • Response.php: response class
    • ResponseInterface.php: the interface that the response object should implement
    • RequestHandler.php: request handler

    Well, in general, everything is almost obvious. Much is clear without even looking inside the classes. But still briefly about everything. The classes of exceptions that are used when appropriate situations arise, all that is done in them is the message and the response code. Request- a request class that parses environment variables, parameters, and everything related to the request. Response- the response class, which contains the branch body, forms headers and everything related to the answer. RequestHandlerIs a request handler. Perhaps consider it in more detail.

    In fact, all that the request handler does is using the event dispatcher (EventDispatcher) passed to it in the parameters to generate various events, thereby informing the application about the various stages of parsing the request and generating a response. And depending on the response of listeners to these events, it terminates or generates the next event.

    List of events that the request handler creates:
    • core.request
    • core.load_controller
    • core.controller
    • core.view
    • core.response
    • core.exception: in case of exceptions

    That is, events reflect the main stages of parsing a request and generating a response. RequestHandlerchecking the reaction of the application to events, it continues to create events or terminates. Accordingly, the application by hanging its handlers on certain events is involved in the formation of the response. However, some parts of the application may not know anything about each other.

    Better, probably all of this to try on an example. Which in general, I will do now. So, stripping Symfony to the goal, removing everything except the kernel and hanging your handler on the event core.request, at the same time there will be a small demonstration of the flexibility of the framework.

    An example will be based on sandbox with an updated version of Symfony, how the environment was created can be seen here .

    So, let's start with the configs. In filehello/config/config.ymlcomment out everything except the line kernel.config: ~. Now fix the application core, filehello/HelloKernel.php

    # hello / HelloKernel.php
    // remove all bundles, with the exception of the kernel and our application
    public function registerBundles ()
    {
      return array (
        new Symfony \ Foundation \ Bundle \ KernelBundle (),
        new Application \ HelloBundle \ Bundle (),
      );
    }
    

    Now, we need to describe the necessary parameters and services in the DI container, for this we first create our extension for the DI container, create a directory src/Application/HelloBundle/DependencyInjection, and in it a file HelloExtension.phpwith the following contents:

    namespace Application \ HelloBundle \ DependencyInjection;
    use Symfony \ Components \ DependencyInjection \ Loader \ LoaderExtension,
        Symfony \ Components \ DependencyInjection \ Loader \ XmlFileLoader,
        Symfony \ Components \ DependencyInjection \ BuilderConfiguration,
        Symfony \ Components \ DependencyInjection \ Reference,
        Symfony \ Components \ DependencyInjection \ Definition;
    class HelloExtension extends LoaderExtension
    {
      public function helloLoad ($ config)
      {
        $ configuration = new BuilderConfiguration ();
        $ loader = new XmlFileLoader (__ DIR __. '/ .. / Resources / config');
        $ configuration-> merge ($ loader-> load ('hello.xml'));
        return $ configuration;
      }
      public function getAlias ​​()
      {
        return 'hello';
      }
      public function getNamespace ()
      {
        return 'http://poulikov.ru/schema/dic/hello';
      }
      public function getXsdValidationBasePath ()
      {
        return __DIR __. '/ .. / Resources / config /';
      }
    }
    

    now register our extension:

    # src / Application / HelloBundle / Bundle.php
    // use our extension
    use Application \ HelloBundle \ DependencyInjection \ HelloExtension;
    ...
    // register the extension in the container
    public function buildContainer (ContainerInterface $ container)
    {
      Loader :: registerExtension (new HelloExtension ());
    }
    

    Our extension will look for a file hello.xmlalong the path src/Application/HelloBundle/Resources/config/hello.xml
    so you need to create this file with approximately the following contents:

    Application \ HelloBundle \ Request \ Parser

    In this file, we defined a service that is hung to listen to the event. core.request
    Now create a request parser:

    # src / Application / HelloBundle / Request / Parser.php
    namespace Application \ HelloBundle \ Request;
    use Symfony \ Components \ DependencyInjection \ ContainerInterface;
    use Symfony \ Components \ EventDispatcher \ Event;
    use Symfony \ Components \ Routing \ RouterInterface;
    class parser
    {
      protected $ container;
      public function __construct (ContainerInterface $ container)
      {
        $ this-> container = $ container;
      }
      public function register ()
      {
        $ this-> container-> getEventDispatcherService () -> connect ('core.request', array ($ this, 'resolve'));
      }
      public function resolve (Event $ event)
      {
        $ response = $ this-> container-> getResponseService ();
        $ response-> setContent ("
    Hello World! I'm symfony 2.0 lite
    "); $ event-> setReturnValue ($ response); $ event-> setProcessed (true); } }

    Now the final touch, in the config hello/config/config.ymlwe add the line hello.hello: ~
    That's all! Now, turning to any address, we get the answer:
    Result
    A completely useless application turned out. But with this example it’s easy to show how it works, you can hook on to other events. Everything is very flexible and convenient.

    Also popular now: