ReactPHP is an event-driven, non-blocking I/O library. This library relies essentially on an event loop that polls file descriptors, uses timers and defers callbacks by registering and executing outstanding ticks on each iteration of the loop.
ReactPHP is based on the Reactor pattern which, according to Douglas C. Schmidt, is a "design pattern that handles service requests that are delivered concurrently to an application by one or more clients. Each service in an application may consist of several methods and is represented by a separate event handler that is responsible for dispatching service-specific requests. Dispatching of event handlers is performed by an initiation dispatcher, which manages the registered event handlers. Demultiplexing of service requests is performed by a synchronous event demultiplexer." In Schmidt’s original paper Reactor: An Object Behavioral Pattern for Demultiplexing and Dispatching Handles for Synchronous Events, we can find this UML representation of this pattern:

Let’s start exploring this asynchronous programming library by installing it in our code repository. On the container’s CLI, enter the following commands:
# cd /srv/www/react # php composer.phar self-update
# php composer.phar install # cd examples
Once the library is installed through Composer, you can try any of the example scripts that you can find in the examples directory. These code examples come from ReactPHP's main code repository. In our case, we will start by having a look at the parallel-download.php script. Here is its source code:
// parallel-download.php $start = microtime(true); // downloading the two best technologies ever in parallel require __DIR__ . DIRECTORY_SEPARATOR .'..' . DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR .'autoload.php'; $loop = React\EventLoop\Factory::create(); $files = array( 'node-v0.6.18.tar.gz' => 'http://nodejs.org/dist/v0.6.18/node-v0.6.18.tar.gz', 'php-5.5.15.tar.gz' => 'http://it.php.net/get/php-5.5.15.tar.gz/from/this/mirror', ); foreach ($files as $file => $url) {
$readStream = fopen($url, 'r'); $writeStream = fopen($file, 'w'); stream_set_blocking($readStream, 0); stream_set_blocking($writeStream, 0); $read = new React\Stream\Stream($readStream, $loop); $write = new React\Stream\Stream($writeStream, $loop); $read->on('end', function () use ($file, &$files) { unset($files[$file]); echo "Finished downloading $file\n"; }); $read->pipe($write);
} $loop->addPeriodicTimer(5, function ($timer) use (&$files) { if (0 === count($files)) { $timer->cancel(); } foreach ($files as $file => $url) {
$mbytes = filesize($file) / (1024 * 1024); $formatted = number_format($mbytes, 3); echo "$file: $formatted MiB\n";
} }); echo "This script will show the download status every 5 seconds.\n"; $loop->run(); $time = microtime(true) - $start; echo 'Time elapsed: ' . $time . PHP_EOL; echo memory_get_usage() . ' bytes' . PHP_EOL;
Essentially, this script creates two streams, sets them to the non-blocking mode and registers the streams with the loop. A timer is added to the loop in order to echo a message every 5 seconds. Finally, it runs the loop.
Let's have a look at this script in action using the following command:
# php parallel-download.php
Here are the results:

As you can see, the downloads were executed in a parallel, asynchronous and reactive way.
Let's continue our short journey into the world of ReactPHP by having a little bit of fun with the tcp-chat.php script that is included in the code examples. Here is the source code of this code example:
// tcp-chat.php
// socket based chat
require __DIR__ . DIRECTORY_SEPARATOR .'..' . DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR .'autoload.php';
$loop = React\EventLoop\Factory::create();
$socket = new React\Socket\Server($loop);
$conns = new \SplObjectStorage();
$socket->on('connection', function ($conn) use ($conns) {
$conns->attach($conn);
$conn->on('data', function ($data) use ($conns, $conn) {
foreach ($conns as $current) {
if ($conn === $current) {
continue;
}
$current->write($conn->getRemoteAddress().': ');
$current->write($data);
}
});
$conn->on('end', function () use ($conns, $conn) {
$conns->detach($conn);
});
});
echo "Socket server listening on port 4000.\n";
echo "You can connect to it by running: telnet localhost 4000\n";
$socket->listen(4000);
$loop->run();
The script creates a socket server that listens on port 4000 and is informed by the loop of incoming connections by listening for a connection event. Upon notification of the event, the socket server injects the connection object into the handler. The connection object then starts listening for the data event which will trigger it to do something with the data received from the socket server's client. In the case of this chat script, the connection object will trigger the write methods of all registered connection objects found in the SplObjectStorage object, thus effectively sending the message to all currently connected chat clients.
First, start the chat server by running the script:
#
Then, open three new Terminal windows and connect to our Linux for PHP Docker container by entering the following commands in each window:
#
On each container's CLI, enter the following command:
Once connected through telnet, just have fun sending messages back and forth from one Terminal window to the other:

Obviously, what has been done here using Terminal windows within the same container could have been done using Terminal windows on different computers through networking. This example shows us just how powerful asynchronous programming can be.
Let's complete our survey of ReactPHP's code examples by having a look at the scalability.php script. Here is its source code:
// scalability.php
// a simple, single-process, horizontal scalable http server listening on 10 ports
require __DIR__ . DIRECTORY_SEPARATOR .'..' . DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR .'autoload.php';
$loop = React\EventLoop\Factory::create();
for ($i = 0; $i < 10; ++$i) {
$s = stream_socket_server('tcp://127.0.0.1:' . (8000 + $i));
$loop->addReadStream($s, function ($s) use ($i) {
$c = stream_socket_accept($s);
$len = strlen($i) + 4;
fwrite($c,"HTTP/1.1 200 OK\r\nContent-Length: $len\r\n\r\nHi:$i\n");
echo "Served on port 800$i\n";
});
}
echo "Access your brand new HTTP server on 127.0.0.1:800x. Replace x with any number from 0-9\n";
$loop->run();
The script creates a socket server which is then attached to the main event loop in order to call a lambda function when a request is sent to the server. The lambda function then executes the code that will send the answer back to the client by writing it to the accepted stream socket.
Let's run this code with the following command:
#
Then, open another Terminal window and connect it to our Linux for PHP Docker container:
#
Then, query the server using wget:
Once done, you should get the following responses for each request:

This is what you should see on the server side:

Again, you can see how powerful ReactPHP can be, as only a few lines of code are enough to create a scalable web server.
Moreover, we highly recommend that all the files from the ReactPHP project that are included in our repository be explored and tried out so you can fully appreciate what this library can do for you as a developer when it comes to asynchronous programming.
Also, there are other great asynchronous PHP libraries that can help you as you master this new way to develop and speed up high latency I/O applications. One such library is Amp (https://amphp.org/). It is well worth the time to explore these very useful libraries while mastering the art of asynchronous programming.
Finally, for more information on asynchronous programming in PHP, you can listen to a great presentation given on this topic by Christopher Pitt at Nomad PHP (https://nomadphp.com/asynchronous-php/).