react php: the nodejs challenger
DESCRIPTION
Event looped, asynchronous programming is possible with PHP! Streams, promises, async IO, web sockets -- you can do it all, with React PHP. Presented by Luke Kysow.TRANSCRIPT
![Page 1: React PHP: the NodeJS challenger](https://reader033.vdocuments.net/reader033/viewer/2022052412/5589000ed8b42a33708b458a/html5/thumbnails/1.jpg)
REACT PHPThe NodeJS Challenger
LUKE KYSOWSoftware Engineer @Hootsuite
Find me on Twitter @lkysow
![Page 2: React PHP: the NodeJS challenger](https://reader033.vdocuments.net/reader033/viewer/2022052412/5589000ed8b42a33708b458a/html5/thumbnails/2.jpg)
What is ReactPHP?
Written by Igor Wiedler • @igorwhiletrue
![Page 3: React PHP: the NodeJS challenger](https://reader033.vdocuments.net/reader033/viewer/2022052412/5589000ed8b42a33708b458a/html5/thumbnails/3.jpg)
$loop = React\EventLoop\Factory::create();$socket = new React\Socket\Server($loop);$http = new React\Http\Server($socket, $loop);
$http->on('request', function ($req, $rep) { $rep->writeHead(); $rep->end("Hello World!\n");});
$socket->listen(8000);$loop->run();
![Page 4: React PHP: the NodeJS challenger](https://reader033.vdocuments.net/reader033/viewer/2022052412/5589000ed8b42a33708b458a/html5/thumbnails/4.jpg)
What Does PHPSuck At?
![Page 5: React PHP: the NodeJS challenger](https://reader033.vdocuments.net/reader033/viewer/2022052412/5589000ed8b42a33708b458a/html5/thumbnails/5.jpg)
C10K Problem
![Page 6: React PHP: the NodeJS challenger](https://reader033.vdocuments.net/reader033/viewer/2022052412/5589000ed8b42a33708b458a/html5/thumbnails/6.jpg)
Websockets
![Page 7: React PHP: the NodeJS challenger](https://reader033.vdocuments.net/reader033/viewer/2022052412/5589000ed8b42a33708b458a/html5/thumbnails/7.jpg)
Making lots of concurrentrequests (ex. Web Scraping)
![Page 8: React PHP: the NodeJS challenger](https://reader033.vdocuments.net/reader033/viewer/2022052412/5589000ed8b42a33708b458a/html5/thumbnails/8.jpg)
Speed
![Page 9: React PHP: the NodeJS challenger](https://reader033.vdocuments.net/reader033/viewer/2022052412/5589000ed8b42a33708b458a/html5/thumbnails/9.jpg)
Why does PHPsuck at solvingthese problems?
![Page 10: React PHP: the NodeJS challenger](https://reader033.vdocuments.net/reader033/viewer/2022052412/5589000ed8b42a33708b458a/html5/thumbnails/10.jpg)
Why is NodeJSgood at solvingthese problems?
![Page 11: React PHP: the NodeJS challenger](https://reader033.vdocuments.net/reader033/viewer/2022052412/5589000ed8b42a33708b458a/html5/thumbnails/11.jpg)
A typical web request<?php
$request = $this->getRequest();$param = $request->getParameter('param');
// these calls block$apiResponse = $api->getSomething($param);$dbResponse = $database->doSomething($param);
return new Response($apiResponse, $dbResponse
![Page 12: React PHP: the NodeJS challenger](https://reader033.vdocuments.net/reader033/viewer/2022052412/5589000ed8b42a33708b458a/html5/thumbnails/12.jpg)
Latency Numbers EveryProgrammer Should Know
L1 cache reference 0.5 nsL2 cache reference 7 nsMain memory reference 100 nsSend 1K bytes over 1 Gbpsnetwork
10,000 ns
Read 1 MB sequentiallyfrom memory
250,000 ns
Round trip within samedatacenter
500,000 ns
![Page 13: React PHP: the NodeJS challenger](https://reader033.vdocuments.net/reader033/viewer/2022052412/5589000ed8b42a33708b458a/html5/thumbnails/13.jpg)
A typical web request<?php
$request = $this->getRequest(); // 1ns$param = $request->getParameter('param'); // 1ns
// 100,000,000 ns$apiResponse = $api->getSomething($param);// 500,000 ns$dbResponse = $database->doSomething($param);
// 1nsreturn new Response($apiResponse, $dbResponse
![Page 14: React PHP: the NodeJS challenger](https://reader033.vdocuments.net/reader033/viewer/2022052412/5589000ed8b42a33708b458a/html5/thumbnails/14.jpg)
Solution:
(╯°□°)╯︵ ┻━┻Implement Non-Blocking I/O
and Event Loops in PHP!
![Page 15: React PHP: the NodeJS challenger](https://reader033.vdocuments.net/reader033/viewer/2022052412/5589000ed8b42a33708b458a/html5/thumbnails/15.jpg)
Aside: Streams
$filePointer = fopen("http://google.com", "rb"
echo stream_get_contents($filePointer, 25);// "<!doctype html><html item"
echo stream_get_contents($filePointer, 25);// "scope="" itemtype="http:/"
![Page 16: React PHP: the NodeJS challenger](https://reader033.vdocuments.net/reader033/viewer/2022052412/5589000ed8b42a33708b458a/html5/thumbnails/16.jpg)
Aside: Streams
$filePointer = fopen("file:///tmp/test", "w"
fwrite($filePointer, "Actual React code coming soon");
![Page 17: React PHP: the NodeJS challenger](https://reader033.vdocuments.net/reader033/viewer/2022052412/5589000ed8b42a33708b458a/html5/thumbnails/17.jpg)
Convert this...<?php
$request = $this->getRequest();$param = $request->getParameter('param');
// these calls block$apiResponse = $api->getSomething($param);$dbResponse = $database->doSomething($param);
return new Response($apiResponse, $dbResponse
![Page 18: React PHP: the NodeJS challenger](https://reader033.vdocuments.net/reader033/viewer/2022052412/5589000ed8b42a33708b458a/html5/thumbnails/18.jpg)
// get requests as streams$apiStream = $api->getStream($param);$dbStream = $database->getStream($param);
// still blockslist($apiResp, $dbResp) = $this->retrieveData($apiStream, $dbStream);
return new Response($apiResp, $dbResp);
![Page 19: React PHP: the NodeJS challenger](https://reader033.vdocuments.net/reader033/viewer/2022052412/5589000ed8b42a33708b458a/html5/thumbnails/19.jpg)
$apiStream = $api->getStream($param); $dbStream = $database->getStream($param);
// return asynchronously $this->retrieveStreams($apiStream, $dbStream ->on('streamsReady',
function($apiResp, $dbResp) { return new Response($apiResp, $dbResp } );
![Page 20: React PHP: the NodeJS challenger](https://reader033.vdocuments.net/reader033/viewer/2022052412/5589000ed8b42a33708b458a/html5/thumbnails/20.jpg)
stream_select
![Page 21: React PHP: the NodeJS challenger](https://reader033.vdocuments.net/reader033/viewer/2022052412/5589000ed8b42a33708b458a/html5/thumbnails/21.jpg)
$filePointer = fopen("http://google.com", "rb"$readable = [$filePointer];$write = []; $exc = []; $t = 5;
if (stream_select($readable, $write, $exc, $t if ($readable) { $googleStream = $readable[0]; echo stream_get_contents($googleStream, // echoes <!doctype html><html item }}
![Page 22: React PHP: the NodeJS challenger](https://reader033.vdocuments.net/reader033/viewer/2022052412/5589000ed8b42a33708b458a/html5/thumbnails/22.jpg)
What do we yield control to?
![Page 23: React PHP: the NodeJS challenger](https://reader033.vdocuments.net/reader033/viewer/2022052412/5589000ed8b42a33708b458a/html5/thumbnails/23.jpg)
An Event Loop<?php
while (true) { $event = $this->getNextEvent(); $event->process();}
![Page 24: React PHP: the NodeJS challenger](https://reader033.vdocuments.net/reader033/viewer/2022052412/5589000ed8b42a33708b458a/html5/thumbnails/24.jpg)
while (true) { if (stream_select($read, $write, $exc, 1)) { if ($read) { foreach ($readable as $stream) { // run callback for that stream } } if ($write) { foreach ($writable as $stream) { // run callback for that stream }} }}
![Page 25: React PHP: the NodeJS challenger](https://reader033.vdocuments.net/reader033/viewer/2022052412/5589000ed8b42a33708b458a/html5/thumbnails/25.jpg)
Non Blocking I/O+ Event Loops== Awesome
![Page 26: React PHP: the NodeJS challenger](https://reader033.vdocuments.net/reader033/viewer/2022052412/5589000ed8b42a33708b458a/html5/thumbnails/26.jpg)
== React PHP
![Page 27: React PHP: the NodeJS challenger](https://reader033.vdocuments.net/reader033/viewer/2022052412/5589000ed8b42a33708b458a/html5/thumbnails/27.jpg)
$loop = React\EventLoop\Factory::create();$socket = new React\Socket\Server($loop);
$socket->on('connection', function ($conn) { $conn->write("Hello there!\n"); $conn->write("Don't say anything...\n");
$conn->on('data', function ($data) use ($conn) { $conn->close(); });});$socket->listen(1337);$loop->run()
![Page 28: React PHP: the NodeJS challenger](https://reader033.vdocuments.net/reader033/viewer/2022052412/5589000ed8b42a33708b458a/html5/thumbnails/28.jpg)
$loop = React\EventLoop\Factory::create();$socket = new React\Socket\Server($loop);$http = new React\Http\Server($socket);
$http->on('request', function ($request, $response) { echo "I see a client!\n"; $response->writeHead(200, ['Content-Type' => 'text/plain']); $response->end("Hello World!\n");});
$socket->listen(1337);$loop->run();
![Page 29: React PHP: the NodeJS challenger](https://reader033.vdocuments.net/reader033/viewer/2022052412/5589000ed8b42a33708b458a/html5/thumbnails/29.jpg)
Pipes$loop = React\EventLoop\Factory::create();$socket = new React\Socket\Server($loop);
$socket->on('connection', function ($conn) { $conn->pipe($conn); });
$socket->listen(1337);$loop->run();
![Page 30: React PHP: the NodeJS challenger](https://reader033.vdocuments.net/reader033/viewer/2022052412/5589000ed8b42a33708b458a/html5/thumbnails/30.jpg)
$waiting = null;$socket->on('connection', function ($conn) use (&$waiting) { if (null === $waiting) { $waiting = $conn; $conn->write("Wait for a partner.\n"); } else { $conn->write("Connected!"); $waiting->write("Connected!");
$conn->pipe($waiting)->pipe($conn); $waiting = null; }});
![Page 31: React PHP: the NodeJS challenger](https://reader033.vdocuments.net/reader033/viewer/2022052412/5589000ed8b42a33708b458a/html5/thumbnails/31.jpg)
React ProjectsReact In The IndustryWeb Scraping with React
![Page 32: React PHP: the NodeJS challenger](https://reader033.vdocuments.net/reader033/viewer/2022052412/5589000ed8b42a33708b458a/html5/thumbnails/32.jpg)
High Performance SymfonyTL;DR: You'll get with this approach almost 2.000 requests/s instead of
130 on a large Symfony app.
Even if you have an "opcode cache" you have todeclare classes, instantiate your objects, read your
caches, etc for every single request. As you can surelyimagine this is very time consuming and far awayfrom being a perfect setup for high performance.
http://marcjschmidt.de/blog/2014/02/08/php-high-performance.html
![Page 33: React PHP: the NodeJS challenger](https://reader033.vdocuments.net/reader033/viewer/2022052412/5589000ed8b42a33708b458a/html5/thumbnails/33.jpg)
Is React PHP aNodeJS
Challenger?
![Page 34: React PHP: the NodeJS challenger](https://reader033.vdocuments.net/reader033/viewer/2022052412/5589000ed8b42a33708b458a/html5/thumbnails/34.jpg)
NO
![Page 35: React PHP: the NodeJS challenger](https://reader033.vdocuments.net/reader033/viewer/2022052412/5589000ed8b42a33708b458a/html5/thumbnails/35.jpg)
Fin
Luke Kysow • @lkysow
Please give me your feedback! http://tiny.cc/reactphp