Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
React (phpbnl13)
Search
Igor Wiedler
January 26, 2013
Programming
1.3k
5
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
React (phpbnl13)
Igor Wiedler
January 26, 2013
More Decks by Igor Wiedler
See All by Igor Wiedler
Redis Bedtime Stories
igorw
1
380
Wide Event Analytics (LISA19)
igorw
4
950
a day in the life of a request
igorw
0
180
production: an owner's manual
igorw
0
200
The Power of 2
igorw
0
350
LISP 1.5 Programmer's Manual: A Dramatic Reading
igorw
0
490
The Moral Character of Software
igorw
1
330
interdisciplinary computing (domcode)
igorw
0
330
miniKanren (clojure berlin)
igorw
1
340
Other Decks in Programming
See All in Programming
GKE アップグレード前に知っておきたい Blue/Green と PDB の関係
stkk
0
160
[GoCon2026] When Goroutines Are Not Enough: Runtime Locality in High-Throughput Go
takehaya
5
700
Family mrubyの進捗
kishima
1
100
AWS DevOps Agentで インシデント対応をAIに任せたい
honmarkhunt
7
2.6k
go-spidermonkeyでAIエージェントのCode Modeを実装する
syumai
3
1.5k
Swift愛好会と私(ウホーイ) / Swift Fan Club and Uhooi
uhooi
0
150
LL言語やWebフレームワークのPostgreSQL対応 〜DBの機能がユーザーに届くまで〜
kentaroutakeda
0
140
【DroidKaigi 2026】「アクセシビリティを利用するとき、 アクセシビリティもまたこちらを利用している」 〜マルウェアによる攻撃と防衛について〜
halunoyo
0
410
高専キャリア LT 発表内容
crysta1221
6
5.6k
一参加者から『中の人』へ 〜全通PHPerがブースに立って学んだ、カンファレンスを100倍楽しむコツ〜
wp_daisuke
0
130
不幸な GC
chencmd
0
890
XHTMLが残したもの
yosuke_furukawa
PRO
2
460
Featured
See All Featured
End of SEO as We Know It (SMX Advanced Version)
ipullrank
3
4.4k
Unsuck your backbone
ammeep
672
58k
The AI Revolution Will Not Be Monopolized: How open-source beats economies of scale, even for LLMs
inesmontani
PRO
3
3.7k
The Hidden Cost of Media on the Web [PixelPalooza 2025]
tammyeverts
2
490
A better future with KSS
kneath
240
18k
Agile that works and the tools we love
rasmusluckow
331
22k
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
254
22k
Context Engineering - Making Every Token Count
addyosmani
9
1.1k
Google's AI Overviews - The New Search
badams
0
1.6k
It's Worth the Effort
3n
188
29k
The Curse of the Amulet
leimatthew05
2
14k
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
12
1.8k
Transcript
None
Y U NO PHP?
@igorwesome
None
None
None
var http = require('http'); var server = new http.Server(); server.on('request',
function (req, res) { res.writeHead(200, {'Content-Type': 'text/plain'}); res.end('Hello World\n'); }); server.listen(1337, '127.0.0.1');
None
$server = stream_socket_server('tcp://127.0.0.1:1337'); while ($conn = stream_socket_accept($server, -1)) { fwrite($conn,
"HTTP/1.1 200 OK\r\n"); fwrite($conn, "Content-Length: 3\r\n\r\n"); fwrite($conn, "Hi\n"); fclose($conn); }
$s=stream_socket_server('tcp://[::1]:81'); while($c=stream_socket_accept($s,-1)) fwrite($c,"HTTP/1.1 200 OK\r\nContent-Length: 2\r\n\r\nHi");
Non-blocking I/O
C10K
Calculations are fast, I/O is slow.
Latency Comparison Numbers -------------------------- L1 cache reference 0.5 ns Branch
mispredict 5 ns L2 cache reference 7 ns Mutex lock/unlock 25 ns Main memory reference 100 ns Compress 1K bytes with Zippy 3,000 ns Send 1K bytes over 1 Gbps network 10,000 ns 0.01 ms Read 4K randomly from SSD* 150,000 ns 0.15 ms Read 1 MB sequentially from memory 250,000 ns 0.25 ms Round trip within same datacenter 500,000 ns 0.5 ms Read 1 MB sequentially from SSD* 1,000,000 ns 1 ms Disk seek 10,000,000 ns 10 ms Read 1 MB sequentially from disk 20,000,000 ns 20 ms Send packet CA->Netherlands->CA 150,000,000 ns 150 ms
Latency Comparison Numbers -------------------------- L1 cache reference 0.5 ns Branch
mispredict 5 ns L2 cache reference 7 ns Mutex lock/unlock 25 ns Main memory reference 100 ns Compress 1K bytes with Zippy 3,000 ns Send 1K bytes over 1 Gbps network 10,000 ns 0.01 ms Read 4K randomly from SSD* 150,000 ns 0.15 ms Read 1 MB sequentially from memory 250,000 ns 0.25 ms Round trip within same datacenter 500,000 ns 0.5 ms Read 1 MB sequentially from SSD* 1,000,000 ns 1 ms Disk seek 10,000,000 ns 10 ms Read 1 MB sequentially from disk 20,000,000 ns 20 ms Send packet CA->Netherlands->CA 150,000,000 ns 150 ms
None
stream_select
$readable = $read ?: null; $writable = $write ?: null;
$except = null; if (stream_select($readable, $writable, $except, 1)) { if ($readable) { foreach ($readable as $stream) { ... } } if ($writable) { foreach ($writable as $stream) { ... } } }
$readable = $read ?: null; $writable = $write ?: null;
$except = null; if (stream_select($readable, $writable, $except, 1)) { if ($readable) { foreach ($readable as $stream) { ... } } if ($writable) { foreach ($writable as $stream) { ... } } } Event Loop
None
None
Event-driven, non-blocking I/O with PHP.
Demo
$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(8080); $loop->run();
$loop = React\EventLoop\Factory::create(); $socket = new React\Socket\Server($loop); $socket->on('connection', function ($conn)
{ $conn->pipe($conn); }); $socket->listen(4000); $loop->run();
None
# composer.json { "require": { "react/http": "0.2.*" } }
$ composer install
Philosophy
Architecture
Événement EventEmitter for PHP
$emitter = new Evenement\EventEmitter(); $emitter->on('data', function ($data) { echo $data;
}); $emitter->emit('data', [$data]);
EventLoop Stream Socket Http
EventLoop $loop = React\EventLoop\Factory::create(); $server = stream_socket_server('tcp://127.0.0.1:8080'); stream_set_blocking($server, 0); $loop->addReadStream($server,
function ($server) use ($loop) { $conn = stream_socket_accept($server); ... });
EventLoop $loop->addPeriodicTimer(5, function () { $memory = memory_get_usage() / 1024;
$formatted = number_format($memory, 3).'K'; echo "Current memory usage: {$formatted}\n"; });
EventLoop $loop->run();
EventLoop backends stream_select libevent libev upcoming libuv
ReadableStream isReadable() pause() resume() close() Events data, end, error, close
Stream
ReadableStream isReadable() pause() resume() close() Events data, end, error, close
Stream
WritableStream isWritable() write($data) end($data) close() Events drain, error, close, pipe
Stream
WritableStream isWritable() write($data) end($data) close() Events drain, error, close, pipe
Stream
Stream $source = new React\Stream\Stream(fopen('omg.txt', 'r'), $loop); $dest = new
React\Stream\Stream(fopen('wtf.txt', 'w'), $loop); $source->pipe($dest);
Stream $a->pipe($b)->pipe($c); a | b | c
Socket $socket = new React\Socket\Server($loop); $socket->on('connection', function ($conn) { $conn->write("Hello
there!\n"); $conn->write("Welcome to this amazing server!\n"); $conn->write("Here's a tip: don't say anything.\n"); $conn->on('data', function ($data) use ($conn) { $conn->close(); }); }); $socket->listen(1337);
Http $socket = new React\Socket\Server($loop); $http = new React\Http\Server($socket); $http->on('request',
function ($request, $response) { $response->writeHead(200, ['Content-Type' => 'text/plain']); $response->end("Hello World!\n"); }); $socket->listen(1337);
EventLoop Stream Socket Http
Http HttpClient DNS
HttpClient Http DNS Stomp Whois
HttpClient Http DNS Stomp Whois WebSocket DNode SOCKS IRC
None
$foo->get(function ($bar) { $bar->get(function ($baz) { $baz->get(function ($bazinga) { $bazinga->get(function
() { throw new FuckItException(); }); }); }); });
async API (escaping callback hell)
React/Async
use React\Async\Util as Async; Async::waterfall([ function ($callback) use ($foo) {
$foo->get($callback); }, function ($bar, $callback) { $bar->get($callback); }, function ($baz, $callback) { $baz->get($callback); }, function ($bazinga, $callback) { $bazinga->get($callback); }, function ($callback) { throw new FuckItException(); } ]);
React/Promise
$dns ->resolve('igor.io') ->then(function ($ip) { echo "Host: $ip\n"; });
$promise ->then('doStuff') ->then('doMoreStuff') ->then('explosion') ->then(null, function ($e) { echo "[Error]
{$e->getMessage()}\n"; });
Deferred Promise Resolver Consumer Producer then() resolve() reject()
Streams
Readable Writable
Readable Writable Through
Readable Writable Through Composite
Buffered Sink
Bi-directional
conn logger parser $conn->pipe($inputLogger)->pipe($parser);
parser client $parser->on('message', function ($message) use ($client) { $client->say('pong'); });
client conn logger $client->pipe($outputLogger)->pipe($conn);
conn parser client conn
Houston we have a blocking call
Inter-process communication
React/ZMQ
$context = new React\ZMQ\Context($loop); $push = $context->getSocket(ZMQ::SOCKET_PUSH); $push->connect('tcp://127.0.0.1:5555'); $push->send('hello');
React/Stomp Predis/Async DNode-PHP
RealtimeWeb™
Ratchet
gifsockets!!!11
None
None
None
Questions? • joind.in/7805 • reactphp.org • @reactphp • @igorwesome
Questions? • joind.in/7805 • reactphp.org • @reactphp • @igorwesome
Http Server Worker Client Worker Worker Client Client HTTP