SlideShare a Scribd company logo
The promise of asynchronous PHP
Wim Godden
Cu.be Solutions
@wimgtr
Who am I ?
Wim Godden (@wimgtr)
Where I'm from
Where I'm from
Where I'm from
Where I'm from
Where I'm from
Where I'm from
My town
My town
Belgium – the traffic
Who am I ?
Wim Godden (@wimgtr)
Founder of Cu.be Solutions (http://cu.be)
Open Source developer since 1997
Developer of PHPCompatibility, OpenX, PHPConsistent, ...
Speaker at Open Source conferences
Who are you ?
Developers ?
Ever worked with asynchronous PHP libraries ?
Node.JS ?
Synchronous processing
Insert
order
Check
payment
Update
stock
Fedex
API
Send
mail
Thank
you
page
Asynchronous processing
Insert
order
Check
payment
Update
stock
Fedex
API
Send
mail
Thank
you
page
Blocking I/O
Disk reading/writing
Network reading/writing
Communication with DB (with some exceptions)
Sending mail
...
Non-blocking = good
Work on multiple things at same time
Not entirely sequential anymore
How do you know something is finished ?
→ Events !
Events
Start
Progress update
End (successfully)
Failed
Callback hell
$one->do(function ($two) {
$two->do(function ($three) {
$three->do(function ($stillcounting) {
$stillcounting->get(function() {
throw new IQuitException();
});
});
});
});
State of asynchronous PHP
Several built-in functions
Several libraries (using the built-in functions)
Facebook Hack
Pthreads
PECL extension
Multithreading
Requires zts (thread-safe)
Pthreads
class WebRequest extends Thread {
public $url;
public $response;
public function __construct($url){
$this->url = $url;
}
public function run() {
$this->response = file_get_contents($this->url);
}
}
$request = new WebRequest("https://cu.be");
if ($request->start()) {
/* do some work here */
$a = array_fill(0, 10000000, 'test');
for ($i = 0; $i < count($a); $i++) {}
/* ensure we have data */
$request->join();
echo $request->response;
}
pcntl_fork
Forks PHP process
Multiprocessing, not multithreading
No communication between processes
No Apache
popen
child.php
<?php
/* Do some work */
echo 'Output here';
main.php
<?php
// open child process
$child = popen('php child.php', 'r');
/*
* Do some work, while already doing other
* work in the child process.
*/
// get response from child (if any) as soon at it's ready:
$response = stream_get_contents($child);
W
arning
: doesn't behave
sam
e
on
all operating
system
s
!
Sequential curl requests
$urls = ['http://www.google.com/', 'http://www.yahoo.com/', 'http://cu.be', 'http://www.microsoft.com/'];
$results = [];
foreach ($urls as $key => $url) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$results[$url] = curl_exec($ch);
curl_close($ch);
}
Asynchronous curl_multi requests
$urls = ['http://www.google.com/', 'http://www.yahoo.com/', 'http://cu.be','http://www.microsoft.com/'];
$chandles = [];
$mh = curl_multi_init();
foreach ($urls as $key => $url) {
$chandles[$key] = curl_init();
curl_setopt($chandles[$key], CURLOPT_URL, $url);
curl_setopt($chandles[$key], CURLOPT_HEADER, 0);
curl_setopt($chandles[$key], CURLOPT_RETURNTRANSFER, 1);
curl_multi_add_handle($mh, $chandles[$key]);
}
$active = null;
do {
$mrc = curl_multi_exec($mh, $active);
} while ($active > 0);
foreach ($chandles as $ch) {
$results[curl_getinfo($ch, CURLINFO_EFFECTIVE_URL)] = curl_multi_getcontent($ch);
curl_multi_remove_handle($mh, $ch);
}
curl_multi_close($mh);
Using Curl as async system
$c = curl_init();
curl_setopt($c, CURLOPT_URL, 'http://somewhere/sub1.php?
action=go&from=4&to=40000');
curl_setopt($c, CURLOPT_FOLLOW_LOCATION, true);
curl_setopt($c, CURLOPT_FRESH_CONNECT, true);
curl_setopt($c, CURLOPT_TIMEOUT_MS, 1);
curl_exec($c);
curl_close($c);
// Code continues after 1ms timeout
main.php
400ms
main.php
100ms
sub1.php
100ms
sub2.php
100ms
sub3.php
100ms
function1()
100ms
function2()
100ms
function3()
100ms
Libevent, libev, libuv
Event handling libraries
PHP extensions (most through PECL)
libevent = also used by Memcached
libev = not available on Windows
ReactPHP
Event-driven non-blocking I/O library
Written in PHP
Provides event-driven interface
Implements event loop
ReactPHP Event Loop
Based on ticks → 1 tick = 1 loop iteration
Timers
One-time timer
Periodic timer
Input/output → callback
ReactPHP – a simple webserver
$loop = new ReactEventLoopFactory::create();
$socket = new ReactSocketServer($loop);
$socket->listen(80);
$http = new ReactHttpServer($socket, $loop);
$http->on('request', function ($request, $response) {
$response->writeHead(200);
$response->send("Hello world!n");
});
$loop->run();
ReactPHP - structure
Event Loop
Stream
Socket
HTTP
→ stream_select (built-in)
libevent (PECL)
libev (PECL)
event (PECL)
ReactPHP - structure
Event Loop
Stream
Socket
HTTPClient DNSWHOIS HTTPClient
WebsocketSOCKS IRC
Timers – one-time
$ourTimer = $loop->addTimer(
15,
function() {
throw new Exception('We have a timeout somewhere');
}
);
$loop->cancelTimer($ourTimer);
Timers - periodic
$aliveTimer = $loop->addPeriodicTimer(
30,
function() use ($host) {
if (isHostAlive($host) === false) {
$loop->cancelTimer($aliveTimer);
throw new Exception('Host ' . $host . ' is dead', HOST_IS_DEAD);
}
}
);
ReactPHP – Promises
$deferred = new SomeclassExtendingPromiseDeferred();
$promise = $deferred->promise()
->then(
function ($value) {
// Resolved, use $value
},
function ($reason) {
// Rejected, show or log $reason
},
function ($status) {
// Progress changed, show or log $status
}
);
ReactPHP – Chaining then() statements
$promise = $deferred->promise()
->then(
function ($a) {
return $a * 2;
}
)
->then(
function ($b) {
return $b * 2;
}
)
->then(
function ($c) {
echo 'c is now ' . $c;
}
);
$deferred->resolve(1); // Will output 'c is now 4'
ReactPHP – Chaining then() statements
$promise = $deferred->promise()
->then(
function ($a) {
if ($a > 5) {
return $a * 2;
} else {
throw new Exception('Too small');
}
}
)
->then(
function ($a) {
echo $a;
},
function ($e) {
echo "We got this exception : " . $e->getMessage();
}
);
$deferred->resolve(10); // Will output 20
$deferred->resolve(1); // Will output : We got this exception : Too small
ReactPHP – Promises example
Hostname lookup – the old way
$hostnames = explode(',', $_POST['hostnames']);
$hostnames = FilterDangerousHostnames($hostnames);
$success = array();
foreach ($hostnames as $hostname) {
$ip = gethostbyname($hostname);
if ($ip != $hostname) {
$success[] = “$hostname ($ip)”;
}
}
echo 'Success resolving ' . implode(', ', $success);
Sequential
→ 10 hostnames → 10 sequential lookups
DNS timeouts → delays
Hostname lookup – the async way
$loop = ReactEventLoopFactory::create();
$factory = new ReactDnsResolverFactory();
$dns = $factory->create('8.8.8.8', $loop);
$hostnames = explode(',', $_POST['hostnames']);
$hostnames = FilterDangerousHostnames($hostnames);
$promises = array();
foreach ($hostnames as $hostname) {
$promises[] = $dns->resolve($hostname)
->then(
function($ip) use ($hostname) {
return "$hostname ($ip)";
},
function($error) { return ''; }
);
}
ReactPromiseall($promises)->then(
function($hostnames) {
$hostnames = array_filter($hostnames, 'strlen');
echo 'Success in resolving ' . implode(', ', $hostnames) . "n";
}
);
$loop->run();
ReactPHP – Promises vs Streams
Promises
→ Very useful
→ But : limited to simple return values
Streams
→ Much more powerful
→ Also somewhat more complex
ReactPHP - Streams
Either :
Readable
Writable
Both
Example :
Through stream = filter
Limited only by your imagination !
$loop = ReactEventLoopFactory::create();
$source = new ReactStreamStream(fopen('source.txt', 'r'), $loop);
$filter = new MyLibStreamAlnumFilter();
$dest = new ReactStreamStream(fopen('dest.txt', 'w'), $loop);
$source->pipe($filter)->pipe($dest);
$loop->run();
$loop = ReactEventLoopFactory::create();
$socket = new ReactSocketServer($loop);
$clients = new SplObjectStorage();
$i = 0;
$socket->on('connection', function($connection) use($clients, &$i) {
$connection->id = ++$i;
$connection->write('Enter your nickname: ');
$connection->on('data', function($message) use($clients, $connection) {
if (empty($connection->nickName)) {
$connection->nickName = $message;
} else {
foreach ($clients as $client) {
if ($client->id == $connection->id) {
continue;
}
$client->write(
sprintf(
'<%s> %s',
$connection->nickName,
$message
)
);
}
}
});
$clients->attach($connection);
});
$socket->listen(1337);
$loop->run();
PubSub using ZeroMQ
$context = new ReactZMQContext($loop);
$pub = $context->getSocket(ZMQ::SOCKET_PUB);
$pub->connect('tcp://127.0.0.1:5555');
$i = 0;
$loop->addPeriodicTimer(1, function () use (&$i, $pub) {
$i++;
$pub->sendmulti(array('phpaustralia', 'Message ' .$i));
});
PubSub using ZeroMQ
$context = new ReactZMQContext($loop);
$sub = $context->getSocket(ZMQ::SOCKET_SUB);
$sub->bind('tcp://127.0.0.1:5555');
$sub->subscribe('phpaustralia');
$sub->on('message', function ($msg) {
echo "Received: $msgn";
});
Based on ReactPHP
Some golden rules & warnings
Golden rule #1 : asynchronous != faster code
Golden rule #2 : don't assume your code will remain as fast
Golden rule #3 : if you don't need a response, don't wait for one
Warning : async does not guarantee execution order !
Questions ?
Questions ?
Thanks !
@wimgtr
wim@cu.be
Please provide some feedback : https://joind.in/talk/9c6da

More Related Content

ODP
My app is secure... I think
ODP
My app is secure... I think
ODP
My app is secure... I think
ODP
The promise of asynchronous PHP
ODP
My app is secure... I think
ODP
My app is secure... I think
PDF
React PHP: the NodeJS challenger
ODP
My app is secure... I think
My app is secure... I think
My app is secure... I think
My app is secure... I think
The promise of asynchronous PHP
My app is secure... I think
My app is secure... I think
React PHP: the NodeJS challenger
My app is secure... I think

What's hot (20)

ODP
My app is secure... I think
ODP
When dynamic becomes static: the next step in web caching techniques
PDF
Asynchronous I/O in PHP
KEY
Perl Web Client
PDF
Nubilus Perl
PDF
PHPCon 2016: PHP7 by Witek Adamus / XSolve
PPTX
ES6 is Nigh
PPTX
Electrify your code with PHP Generators
ODP
My app is secure... I think
PDF
News of the Symfony2 World
ODP
Beyond PHP - it's not (just) about the code
KEY
PDF
Advanced symfony Techniques
PPTX
Speed up your developments with Symfony2
PDF
The state of your own hypertext preprocessor
KEY
Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011
PPTX
Python and EM CLI: The Enterprise Management Super Tools
PDF
PHP 5.3 and Lithium: the most rad php framework
PDF
Doctrine fixtures
PDF
Rich Model And Layered Architecture in SF2 Application
My app is secure... I think
When dynamic becomes static: the next step in web caching techniques
Asynchronous I/O in PHP
Perl Web Client
Nubilus Perl
PHPCon 2016: PHP7 by Witek Adamus / XSolve
ES6 is Nigh
Electrify your code with PHP Generators
My app is secure... I think
News of the Symfony2 World
Beyond PHP - it's not (just) about the code
Advanced symfony Techniques
Speed up your developments with Symfony2
The state of your own hypertext preprocessor
Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011
Python and EM CLI: The Enterprise Management Super Tools
PHP 5.3 and Lithium: the most rad php framework
Doctrine fixtures
Rich Model And Layered Architecture in SF2 Application
Ad

Viewers also liked (6)

ODP
Is your code ready for PHP 7 ?
ODP
The promise of asynchronous php
PPTX
Distributed Applications with Perl & Gearman
PPTX
ZeroMQ: Super Sockets - by J2 Labs
PPT
Asynchronous PHP. Myth? Reality!
PDF
Consuming RESTful services in PHP
Is your code ready for PHP 7 ?
The promise of asynchronous php
Distributed Applications with Perl & Gearman
ZeroMQ: Super Sockets - by J2 Labs
Asynchronous PHP. Myth? Reality!
Consuming RESTful services in PHP
Ad

Similar to The promise of asynchronous php (20)

ODP
The promise of asynchronous PHP
PDF
ReactPHP
PDF
Asynchronous PHP and Real-time Messaging
PDF
When symfony met promises
PDF
Asynchronous PHP | Codesushi - Warsaw 2017
PDF
Generating Power with Yield
PDF
Zend con 2016 - Asynchronous Prorgamming in PHP
PDF
php[world] 2016 - You Don’t Need Node.js - Async Programming in PHP
PDF
Meet a parallel, asynchronous PHP world
PDF
Build a bot workshop async primer - php[tek]
PDF
You Got Async in my PHP!
PPTX
PDF
ZendCon 2017 - Build a Bot Workshop - Async Primer
PDF
Php 5.6 From the Inside Out
PDF
From Generator to Fiber the Road to Coroutine in PHP
PPTX
How to Supercharge your PHP Web API
PDF
2019 11-bgphp
PDF
The most exciting features of PHP 7.1
PPT
PHP CLI: A Cinderella Story
PPTX
Day02 a pi.
The promise of asynchronous PHP
ReactPHP
Asynchronous PHP and Real-time Messaging
When symfony met promises
Asynchronous PHP | Codesushi - Warsaw 2017
Generating Power with Yield
Zend con 2016 - Asynchronous Prorgamming in PHP
php[world] 2016 - You Don’t Need Node.js - Async Programming in PHP
Meet a parallel, asynchronous PHP world
Build a bot workshop async primer - php[tek]
You Got Async in my PHP!
ZendCon 2017 - Build a Bot Workshop - Async Primer
Php 5.6 From the Inside Out
From Generator to Fiber the Road to Coroutine in PHP
How to Supercharge your PHP Web API
2019 11-bgphp
The most exciting features of PHP 7.1
PHP CLI: A Cinderella Story
Day02 a pi.

More from Wim Godden (19)

PDF
Beyond php - it's not (just) about the code
PDF
Bringing bright ideas to life
PDF
The why and how of moving to php 8
PDF
The why and how of moving to php 7
PDF
My app is secure... I think
PDF
My app is secure... I think
PDF
Building interactivity with websockets
PDF
Bringing bright ideas to life
ODP
Your app lives on the network - networking for web developers
ODP
The why and how of moving to php 7.x
ODP
The why and how of moving to php 7.x
ODP
Beyond php - it's not (just) about the code
ODP
Building interactivity with websockets
ODP
Your app lives on the network - networking for web developers
ODP
My app is secure... I think
ODP
Practical git for developers
ODP
Beyond php - it's not (just) about the code
ODP
When dynamic becomes static
ODP
When dynamic becomes static
Beyond php - it's not (just) about the code
Bringing bright ideas to life
The why and how of moving to php 8
The why and how of moving to php 7
My app is secure... I think
My app is secure... I think
Building interactivity with websockets
Bringing bright ideas to life
Your app lives on the network - networking for web developers
The why and how of moving to php 7.x
The why and how of moving to php 7.x
Beyond php - it's not (just) about the code
Building interactivity with websockets
Your app lives on the network - networking for web developers
My app is secure... I think
Practical git for developers
Beyond php - it's not (just) about the code
When dynamic becomes static
When dynamic becomes static

Recently uploaded (20)

PDF
Encapsulation_ Review paper, used for researhc scholars
PPT
Teaching material agriculture food technology
PPTX
Digital-Transformation-Roadmap-for-Companies.pptx
PPTX
SOPHOS-XG Firewall Administrator PPT.pptx
PDF
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
PPTX
Spectroscopy.pptx food analysis technology
PDF
August Patch Tuesday
PDF
Profit Center Accounting in SAP S/4HANA, S4F28 Col11
PPTX
1. Introduction to Computer Programming.pptx
PDF
Per capita expenditure prediction using model stacking based on satellite ima...
PDF
Machine learning based COVID-19 study performance prediction
PDF
Accuracy of neural networks in brain wave diagnosis of schizophrenia
PDF
Assigned Numbers - 2025 - Bluetooth® Document
PDF
Building Integrated photovoltaic BIPV_UPV.pdf
PPTX
Tartificialntelligence_presentation.pptx
PDF
A comparative study of natural language inference in Swahili using monolingua...
PPTX
cloud_computing_Infrastucture_as_cloud_p
PPTX
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
PDF
Unlocking AI with Model Context Protocol (MCP)
PDF
Agricultural_Statistics_at_a_Glance_2022_0.pdf
Encapsulation_ Review paper, used for researhc scholars
Teaching material agriculture food technology
Digital-Transformation-Roadmap-for-Companies.pptx
SOPHOS-XG Firewall Administrator PPT.pptx
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
Spectroscopy.pptx food analysis technology
August Patch Tuesday
Profit Center Accounting in SAP S/4HANA, S4F28 Col11
1. Introduction to Computer Programming.pptx
Per capita expenditure prediction using model stacking based on satellite ima...
Machine learning based COVID-19 study performance prediction
Accuracy of neural networks in brain wave diagnosis of schizophrenia
Assigned Numbers - 2025 - Bluetooth® Document
Building Integrated photovoltaic BIPV_UPV.pdf
Tartificialntelligence_presentation.pptx
A comparative study of natural language inference in Swahili using monolingua...
cloud_computing_Infrastucture_as_cloud_p
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
Unlocking AI with Model Context Protocol (MCP)
Agricultural_Statistics_at_a_Glance_2022_0.pdf

The promise of asynchronous php

  • 1. The promise of asynchronous PHP Wim Godden Cu.be Solutions @wimgtr
  • 2. Who am I ? Wim Godden (@wimgtr)
  • 11. Belgium – the traffic
  • 12. Who am I ? Wim Godden (@wimgtr) Founder of Cu.be Solutions (http://cu.be) Open Source developer since 1997 Developer of PHPCompatibility, OpenX, PHPConsistent, ... Speaker at Open Source conferences
  • 13. Who are you ? Developers ? Ever worked with asynchronous PHP libraries ? Node.JS ?
  • 16. Blocking I/O Disk reading/writing Network reading/writing Communication with DB (with some exceptions) Sending mail ...
  • 17. Non-blocking = good Work on multiple things at same time Not entirely sequential anymore How do you know something is finished ? → Events !
  • 19. Callback hell $one->do(function ($two) { $two->do(function ($three) { $three->do(function ($stillcounting) { $stillcounting->get(function() { throw new IQuitException(); }); }); }); });
  • 20. State of asynchronous PHP Several built-in functions Several libraries (using the built-in functions) Facebook Hack
  • 22. Pthreads class WebRequest extends Thread { public $url; public $response; public function __construct($url){ $this->url = $url; } public function run() { $this->response = file_get_contents($this->url); } } $request = new WebRequest("https://cu.be"); if ($request->start()) { /* do some work here */ $a = array_fill(0, 10000000, 'test'); for ($i = 0; $i < count($a); $i++) {} /* ensure we have data */ $request->join(); echo $request->response; }
  • 23. pcntl_fork Forks PHP process Multiprocessing, not multithreading No communication between processes No Apache
  • 24. popen child.php <?php /* Do some work */ echo 'Output here'; main.php <?php // open child process $child = popen('php child.php', 'r'); /* * Do some work, while already doing other * work in the child process. */ // get response from child (if any) as soon at it's ready: $response = stream_get_contents($child); W arning : doesn't behave sam e on all operating system s !
  • 25. Sequential curl requests $urls = ['http://www.google.com/', 'http://www.yahoo.com/', 'http://cu.be', 'http://www.microsoft.com/']; $results = []; foreach ($urls as $key => $url) { $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_HEADER, 0); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); $results[$url] = curl_exec($ch); curl_close($ch); }
  • 26. Asynchronous curl_multi requests $urls = ['http://www.google.com/', 'http://www.yahoo.com/', 'http://cu.be','http://www.microsoft.com/']; $chandles = []; $mh = curl_multi_init(); foreach ($urls as $key => $url) { $chandles[$key] = curl_init(); curl_setopt($chandles[$key], CURLOPT_URL, $url); curl_setopt($chandles[$key], CURLOPT_HEADER, 0); curl_setopt($chandles[$key], CURLOPT_RETURNTRANSFER, 1); curl_multi_add_handle($mh, $chandles[$key]); } $active = null; do { $mrc = curl_multi_exec($mh, $active); } while ($active > 0); foreach ($chandles as $ch) { $results[curl_getinfo($ch, CURLINFO_EFFECTIVE_URL)] = curl_multi_getcontent($ch); curl_multi_remove_handle($mh, $ch); } curl_multi_close($mh);
  • 27. Using Curl as async system $c = curl_init(); curl_setopt($c, CURLOPT_URL, 'http://somewhere/sub1.php? action=go&from=4&to=40000'); curl_setopt($c, CURLOPT_FOLLOW_LOCATION, true); curl_setopt($c, CURLOPT_FRESH_CONNECT, true); curl_setopt($c, CURLOPT_TIMEOUT_MS, 1); curl_exec($c); curl_close($c); // Code continues after 1ms timeout main.php 400ms main.php 100ms sub1.php 100ms sub2.php 100ms sub3.php 100ms function1() 100ms function2() 100ms function3() 100ms
  • 28. Libevent, libev, libuv Event handling libraries PHP extensions (most through PECL) libevent = also used by Memcached libev = not available on Windows
  • 29. ReactPHP Event-driven non-blocking I/O library Written in PHP Provides event-driven interface Implements event loop
  • 30. ReactPHP Event Loop Based on ticks → 1 tick = 1 loop iteration Timers One-time timer Periodic timer Input/output → callback
  • 31. ReactPHP – a simple webserver $loop = new ReactEventLoopFactory::create(); $socket = new ReactSocketServer($loop); $socket->listen(80); $http = new ReactHttpServer($socket, $loop); $http->on('request', function ($request, $response) { $response->writeHead(200); $response->send("Hello world!n"); }); $loop->run();
  • 32. ReactPHP - structure Event Loop Stream Socket HTTP → stream_select (built-in) libevent (PECL) libev (PECL) event (PECL)
  • 33. ReactPHP - structure Event Loop Stream Socket HTTPClient DNSWHOIS HTTPClient WebsocketSOCKS IRC
  • 34. Timers – one-time $ourTimer = $loop->addTimer( 15, function() { throw new Exception('We have a timeout somewhere'); } ); $loop->cancelTimer($ourTimer);
  • 35. Timers - periodic $aliveTimer = $loop->addPeriodicTimer( 30, function() use ($host) { if (isHostAlive($host) === false) { $loop->cancelTimer($aliveTimer); throw new Exception('Host ' . $host . ' is dead', HOST_IS_DEAD); } } );
  • 36. ReactPHP – Promises $deferred = new SomeclassExtendingPromiseDeferred(); $promise = $deferred->promise() ->then( function ($value) { // Resolved, use $value }, function ($reason) { // Rejected, show or log $reason }, function ($status) { // Progress changed, show or log $status } );
  • 37. ReactPHP – Chaining then() statements $promise = $deferred->promise() ->then( function ($a) { return $a * 2; } ) ->then( function ($b) { return $b * 2; } ) ->then( function ($c) { echo 'c is now ' . $c; } ); $deferred->resolve(1); // Will output 'c is now 4'
  • 38. ReactPHP – Chaining then() statements $promise = $deferred->promise() ->then( function ($a) { if ($a > 5) { return $a * 2; } else { throw new Exception('Too small'); } } ) ->then( function ($a) { echo $a; }, function ($e) { echo "We got this exception : " . $e->getMessage(); } ); $deferred->resolve(10); // Will output 20 $deferred->resolve(1); // Will output : We got this exception : Too small
  • 40. Hostname lookup – the old way $hostnames = explode(',', $_POST['hostnames']); $hostnames = FilterDangerousHostnames($hostnames); $success = array(); foreach ($hostnames as $hostname) { $ip = gethostbyname($hostname); if ($ip != $hostname) { $success[] = “$hostname ($ip)”; } } echo 'Success resolving ' . implode(', ', $success); Sequential → 10 hostnames → 10 sequential lookups DNS timeouts → delays
  • 41. Hostname lookup – the async way $loop = ReactEventLoopFactory::create(); $factory = new ReactDnsResolverFactory(); $dns = $factory->create('8.8.8.8', $loop); $hostnames = explode(',', $_POST['hostnames']); $hostnames = FilterDangerousHostnames($hostnames); $promises = array(); foreach ($hostnames as $hostname) { $promises[] = $dns->resolve($hostname) ->then( function($ip) use ($hostname) { return "$hostname ($ip)"; }, function($error) { return ''; } ); } ReactPromiseall($promises)->then( function($hostnames) { $hostnames = array_filter($hostnames, 'strlen'); echo 'Success in resolving ' . implode(', ', $hostnames) . "n"; } ); $loop->run();
  • 42. ReactPHP – Promises vs Streams Promises → Very useful → But : limited to simple return values Streams → Much more powerful → Also somewhat more complex
  • 43. ReactPHP - Streams Either : Readable Writable Both Example : Through stream = filter Limited only by your imagination ! $loop = ReactEventLoopFactory::create(); $source = new ReactStreamStream(fopen('source.txt', 'r'), $loop); $filter = new MyLibStreamAlnumFilter(); $dest = new ReactStreamStream(fopen('dest.txt', 'w'), $loop); $source->pipe($filter)->pipe($dest); $loop->run();
  • 44. $loop = ReactEventLoopFactory::create(); $socket = new ReactSocketServer($loop); $clients = new SplObjectStorage(); $i = 0; $socket->on('connection', function($connection) use($clients, &$i) { $connection->id = ++$i; $connection->write('Enter your nickname: '); $connection->on('data', function($message) use($clients, $connection) { if (empty($connection->nickName)) { $connection->nickName = $message; } else { foreach ($clients as $client) { if ($client->id == $connection->id) { continue; } $client->write( sprintf( '<%s> %s', $connection->nickName, $message ) ); } } }); $clients->attach($connection); }); $socket->listen(1337); $loop->run();
  • 45. PubSub using ZeroMQ $context = new ReactZMQContext($loop); $pub = $context->getSocket(ZMQ::SOCKET_PUB); $pub->connect('tcp://127.0.0.1:5555'); $i = 0; $loop->addPeriodicTimer(1, function () use (&$i, $pub) { $i++; $pub->sendmulti(array('phpaustralia', 'Message ' .$i)); });
  • 46. PubSub using ZeroMQ $context = new ReactZMQContext($loop); $sub = $context->getSocket(ZMQ::SOCKET_SUB); $sub->bind('tcp://127.0.0.1:5555'); $sub->subscribe('phpaustralia'); $sub->on('message', function ($msg) { echo "Received: $msgn"; });
  • 48. Some golden rules & warnings Golden rule #1 : asynchronous != faster code Golden rule #2 : don't assume your code will remain as fast Golden rule #3 : if you don't need a response, don't wait for one Warning : async does not guarantee execution order !
  • 51. Thanks ! @wimgtr [email protected] Please provide some feedback : https://joind.in/talk/9c6da