Introduce React PHP
Context
On a recent Angular 5 training I could luckily attend to, trainer introduces JS reactive programming (using RXJS). Complete new paradigm as everything is event, nested one with others. Way different way to code... But extremely powerful.
Then I tought : what a wonderful way to stick to my home automation real life modeling. As a matter of fact, IoT and home automation are mainly composed of stimuli and reactions.
What could be better in this context than reactive loop to events? That's what lead me to ReactPHP, which is a PHP implementation of Reactor pattern. This library is very well-done, concern separated.
Few examples
Main brick : event-loop
Factory for loop object creation
$loop = React\EventLoop\Factory::create();
Behind the scenes, this named constructor will use the best scenario according to your configuration.
public static function create()
{
// @codeCoverageIgnoreStart
if (class_exists('libev\EventLoop', false)) {
return new ExtLibevLoop();
} elseif (class_exists('EvLoop', false)) {
return new ExtEvLoop();
} elseif (class_exists('EventBase', false)) {
return new ExtEventLoop();
} elseif (function_exists('event_base_new') && PHP_VERSION_ID < 70000) {
// only use ext-libevent on PHP < 7 for now
return new ExtLibeventLoop();
}
return new StreamSelectLoop();
// @codeCoverageIgnoreEnd
}
More details on differents implementations and extensions related here. So far I'm using the fallback one (StreamSelect) but will enhance this point soon.
Loop run
$loop->run();
Short and sweet. This must be the script last instruction because it will enter in infinite loop from here.
Timers
```php $loop->addTimer(0.8, function () { echo 'world!' . PHP_EOL; });
$loop->addTimer(0.3, function () { echo 'hello '; }); $loop->run(); ```
Here start the magic. The above script will echo 'hello' 0.3s after script beginning then 'world' at 0.5s (0.8s from start). No matter timer registration order, loop will handle orders. Thanks to closures/callbacks, you can put your processes inline for shortness.
Note: you can (and certainly will) use the use
keyword to port any variables in the callback code block context.
```php function hello($name, LoopInterface $loop) { $loop->addTimer(1.0, function () use ($name) { echo "hello $name\n"; }); }
hello('Tester', $loop); $loop->run(); ```
stream
ReadableStreamInterface
```php $stream->on('data', function ($data) { echo $data; });
$loop->run(); ```
Forr example, the end event will be emitted once the source stream has successfully reached the end of the stream (EOF).
```php $stream->on('end', function () { echo 'END'; });
$loop->run(); ```
Among available events: pipe, pause, resume, close...
WritableStreamInterface
Same idea write-oriented.
As far as I write this, this is only what I can practically test and use.
More to be discussed here in future : socket, promise...