Coroutines
OpenSwoole coroutines are cooperative — they yield only on I/O, making parallel fetch trivial. ZealPHP enables HOOK_ALL so all PHP I/O (file, curl, PDO) becomes coroutine-aware automatically.
GET
Parallel fetch — 3 coroutines in 1s not 3s
$app->route('/demo/coroutine/parallel', function() {
$ch = new Channel(3);
$start = microtime(true);
go(fn() => [$ch->push(simulated_fetch('users', 1))]);
go(fn() => [$ch->push(simulated_fetch('orders', 1))]);
go(fn() => [$ch->push(simulated_fetch('stats', 1))]);
$results = [];
for ($i = 0; $i < 3; $i++) $results[] = $ch->pop();
return ['results' => $results, 'elapsed_s' => round(microtime(true) - $start, 3)];
// All 3 run in parallel → ~1s total, not 3s
});
LIVE OUTPUT
Click Run →
GET
Channel — producer/consumer pattern
$app->route('/demo/coroutine/channel', function() {
$ch = new Channel(1); // buffer of 1
go(function() use ($ch) {
co::sleep(1);
$ch->push(['value' => 42, 'from' => 'producer coroutine']);
});
$result = $ch->pop(); // blocks until producer pushes
return ['received' => $result, 'pattern' => 'producer/consumer'];
});
LIVE OUTPUT
Click Run →
How it works
| Primitive | Purpose |
|---|---|
go(callable) | Spawn a coroutine. Runs concurrently when current coroutine yields. |
co::sleep(float $s) | Yield for N seconds without blocking the event loop. |
new Channel(int $capacity) | Buffered queue for coroutine communication. push() + pop(). |
usleep(int $us) | Coroutine-aware micro-sleep under HOOK_ALL (use for sub-second delays). |
OpenSwoole\Runtime::HOOK_ALL | Makes all PHP I/O — curl, file, PDO, sleep — yield the event loop. |
App::superglobals(false) must be called before App::init() to enable coroutine mode.
In coroutine mode, every request runs in its own coroutine with isolated
G::instance() state.