ReactPHP speeds up PHPixie 8x

    image
    ReactPHP is a socket server in PHP created for continuous processing of requests, in contrast to the standard approach with Apache and Nginx where the process dies after processing a single request. Since the code is initialized this way only once, on a separate request we miss the whole overhead from loading classes, starting the framework, reading the configuration, etc.

    The limitation here is that the programmer must remember that the process and all services raised will be used many times and therefore access to the global or static scopes is not desirable. This makes it difficult to use ReactPHP with most frameworks not built for this approach.

    Fortunately, PHPixie itself has abandoned global and static scopes, which makes it easy to run it from under ReactPHP.


    First, add his support to the project:
    php ~/composer.phar require react/react
    


    Then create the react.php file in the root folder:
    registerDebugHandlers(false, false);
    $app = function ($request, $response) use ($framework, $host, $port) {
        $http = $framework->builder()->components()->http();
        // Строим реальную URI запроса
        $uri = 'http://'.$host.':'.$port.$request->getPath();
        $uri = $http->messages()->uri($uri);
        // Приводим запрос к PSR-7
        $serverRequest = $http->messages()->serverRequest(
            $request->getHttpVersion(),
            $request->getHeaders(),
            '',
            $request->getMethod(),
            $uri,
            array(),
            $request->getQuery(),
            array(),
            array(),
            array()
        );
        // Передаем запрос в фреймворк
        $frameworkResponse = $framework
            ->processHttpServerRequest($serverRequest);
        // Вывод ответа
        $response->writeHead(
            $frameworkResponse->getStatusCode(),
            $frameworkResponse->getHeaders()
        );
        $response->end(
            $frameworkResponse->getBody()
        );
    };
    $loop = React\EventLoop\Factory::create();
    $socket = new React\Socket\Server($loop);
    $http = new React\Http\Server($socket);
    $http->on('request', $app);
    $socket->listen($port);
    $loop->run();
    


    We launch:
    php react.php
    


    Now, following the link localhost : 1337 / we see the same PHPixie only running as a server. A simple benchmark on the default controller showed a performance increase of about 8 times, which is not surprising if you take into account how much less code is executed with each request. For those who want to repeat my experiment, notice that I have achieved the best result with the event library as a backend for ReactPHP (it can work without it, but it only turns out a little slower).

    True, ReactPHP itself introduces several limitations. First, you still need a web server for static files. But the saddest thing is that out of the box it does not support data from the request body ($ _POST), although there are ways to achieve this .

    The presence of a constant runtime opens up interesting possibilities, such as creating a chat without the need for an external database. Of course, for now this is only an experiment, but if the idea takes root then PHPixie can get a separate component with wider support for ReactPHP, including for example sessions and file uploads.

    Also popular now: