Developer Blog

  • Blog
  • /
  • Increasing PHPixie Performance with ReactPHP
By Dracony on 12 August 2015

ReactPHP is an event-driven socket server written in PHP that is meant to run peristently unlike the standard Apache/Nginx approach where each request is handled by a separate process. This means it only needs to bootstrap your code once and then continuously feed it requests. It cuts away all the boilerplate of autoloading classes, initializing the framework, reading config files etc. every time.

The limitation here is that the developer has to keep in mind that the process and all services are going to be reused, so any kind of global or static scope has to be avoided as much as possible. This makes it hard to use it with frameworks that were not especially designed for it.

Luckily PHPixie already avoids global scope and an initialized framework can easily be reused. Here is all you need to run a PHPixie project with React:

1
2
# Add ReactPHP with composer
php ~/composer.phar require react/react

Create a react.php file in your projects root folder:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
<?php

require_once('vendor/autoload.php');

$host = 'localhost';
$port = 1337;

$framework = new Project\Framework();
$framework->registerDebugHandlers(false, false);

$app = function ($request, $response) use ($framework, $host, $port) {
    $http = $framework->builder()->components()->http();

    //Build request URI
    $uri = 'http://'.$host.':'.$port.$request->getPath();
    $uri = $http->messages()->uri($uri);

    //Build a PSR7 ServerRequest
    $serverRequest = $http->messages()->serverRequest(
        $request->getHttpVersion(),
        $request->getHeaders(),
        '',
        $request->getMethod(),
        $uri,
        array(),
        $request->getQuery(),
        array(),
        array(),
        array()
    );

    // Process the request
    $frameworkResponse = $framework
        ->processHttpServerRequest($serverRequest);

    // Output response
    $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();
1
2
# Run it
php react.php

Now visit http://localhost:1337/ in your browser and you should see PHPixie running under React. A simple benchmark reported about an 800% performance increase, which is a rather obvious result considering that each request now executes a far less amount a code. ReactPHP supports multiple event backends, I ended up using the one named simply event.

There are some limitations to using it though. You still need a web server for your static files. There also seems to be an issue with getting POST data from the request, React does not provide an easy way to get those, although there is a workaround for it.

Having a persistent runtime also allows for some interesting use cases, such as chat clients that don’t require any kinf of persistence, etc. If the idea of using PHPixie from within React looks interesting to the community I might release a sperate component to allow a wider support for it and an easier setup.

comments powered by Disqus