Skip to content

Instantly share code, notes, and snippets.

@aurelijusb
Last active June 5, 2019 17:38
Show Gist options
  • Save aurelijusb/cc18fc9e856b42753075906e3f96bffc to your computer and use it in GitHub Desktop.
Save aurelijusb/cc18fc9e856b42753075906e3f96bffc to your computer and use it in GitHub Desktop.
VilniusPHP 0x4F: Coroutines in PHP: HTTP example

Code examples: Coroutines in PHP

HTTP (cURL) example

Usage

docker-compose up

Open 127.0.0.1:8000

Where:

Reference

Output

data: 0

data: 1

data: 2

data: 3

data: 4

2019-06-05 17:35:57.484100 Receiving...
2019-06-05 17:36:02.490600 Received
2019-06-05 17:36:02.491000 Closed
2019-06-05 17:36:02.491200  Transformation started
2019-06-05 17:36:02.491300    Result: data: 0
2019-06-05 17:36:02.991700  Transformation finished
2019-06-05 17:36:02.991900  Transformation started
2019-06-05 17:36:02.992200    Result: data: 1
2019-06-05 17:36:03.492400  Transformation finished
2019-06-05 17:36:03.492600  Transformation started
2019-06-05 17:36:03.492700    Result: data: 2
2019-06-05 17:36:03.992900  Transformation finished
2019-06-05 17:36:03.993200  Transformation started
2019-06-05 17:36:03.993300    Result: data: 3
2019-06-05 17:36:04.493500  Transformation finished
2019-06-05 17:36:04.493800  Transformation started
2019-06-05 17:36:04.493900    Result: data: 4
2019-06-05 17:36:04.994200  Transformation finished
2019-06-05 17:36:04.994400  Transformation started
2019-06-05 17:36:04.994500    Result: 
2019-06-05 17:36:05.494800  Transformation finished
2019-06-05 17:36:05.494900 Took: 8.01
2019-06-05 17:35:58.445000 Receiving...
2019-06-05 17:35:59.639100  <<< RECEIVED
2019-06-05 17:35:59.639200  Transformation started
2019-06-05 17:35:59.639300    Result: data: 0
2019-06-05 17:36:00.139500  Transformation finished
2019-06-05 17:36:00.639200  <<< RECEIVED
2019-06-05 17:36:00.639300  Transformation started
2019-06-05 17:36:00.639400    Result: data: 1
2019-06-05 17:36:01.139500  Transformation finished
2019-06-05 17:36:01.639600  <<< RECEIVED
2019-06-05 17:36:01.639800  Transformation started
2019-06-05 17:36:01.639900    Result: data: 2
2019-06-05 17:36:02.140100  Transformation finished
2019-06-05 17:36:02.639800  <<< RECEIVED
2019-06-05 17:36:02.640000  Transformation started
2019-06-05 17:36:02.640000    Result: data: 3
2019-06-05 17:36:03.140200  Transformation finished
2019-06-05 17:36:03.640200  <<< RECEIVED
2019-06-05 17:36:03.640400  Transformation started
2019-06-05 17:36:03.640600    Result: data: 4
2019-06-05 17:36:04.140800  Transformation finished
2019-06-05 17:36:04.141200 Received
2019-06-05 17:36:04.141400 Closed
2019-06-05 17:36:04.141500 Took: 5.7
<?php
function debug($message)
{
$now = DateTime::createFromFormat('U.u', microtime(true));
print $now->format("Y-m-d H:i:s.u") . ' ' . $message . PHP_EOL;
flush();
ob_flush();
}
function transform($data)
{
debug(" Transformation started");
debug(" Result: " . trim($data));
usleep(500000);
debug(" Transformation finished");
}
$reader = function ($curl, $data) {
debug(" <<< RECEIVED");
transform($data);
return strlen($data);
};
function receive($url, $reader)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_WRITEFUNCTION, $reader);
debug("Receiving...");
$output = curl_exec($ch);
debug("Received");
curl_close($ch);
debug("Closed");
return explode("\n\n", $output);
}
header('Content-type: text/plain');
$started = microtime(true);
$result = receive('http://example.nginx/sse.php', $reader);
$took = microtime(true) - $started;
debug("Took: " . round($took, 2));
<?php
function debug($message)
{
$now = DateTime::createFromFormat('U.u', microtime(true));
print $now->format("Y-m-d H:i:s.u") . ' ' . $message . PHP_EOL;
flush();
ob_flush();
}
function transform($data)
{
debug(" Transformation started");
debug(" Result: " . trim($data));
usleep(500000);
debug(" Transformation finished");
}
function receive($url)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
debug("Receiving...");
$output = curl_exec($ch);
debug("Received");
curl_close($ch);
debug("Closed");
return explode("\n\n", $output);
}
header('Content-type: text/plain');
$started = microtime(true);
$result = receive('http://example.nginx/sse.php');
foreach ($result as $item) {
transform($item);
}
$took = microtime(true) - $started;
debug("Took: " . round($took, 2));
version: '2.1'
services:
example.nginx:
container_name: example.nginx
image: nginx:1.14.0
ports:
- "127.0.0.1:8000:80"
volumes:
- ./nginx-site.conf:/etc/nginx/conf.d/site.conf:ro
- ./:/code
example.php:
container_name: example.php
image: php:7.3.3-fpm
volumes:
- ./:/code
<a href="sse.php">Input service</a>
<br/>
<a href="client-simple.php">Simple</a>
<br/>
<a href="client-reactive.php">Reactive</a>
server {
listen 80 default_server;
server_name _;
index index.php index.html;
root /code;
location / {
# try to serve file directly, fallback to index.php
try_files $uri /index.php$is_args$args;
}
location ~ \.php$ {
# Links to other container by its name
resolver 127.0.0.11 valid=10s;
set $upstream_example_php example.php;
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass $upstream_example_php:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_buffering off;
proxy_buffering off;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
}
<?php
//header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
for ($i = 0; $i < 5; $i++) {
print "data: $i\n\n";
usleep(1000000);
flush();
ob_flush();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment