Async frameworks like AMPHP and ReactPHP rely on Fibers to make concurrent I/O look like ordinary synchronous code.
A Fiber (PHP 8.1) is a function with its own call stack that can pause itself anywhere and be resumed later. Unlike a generator, it can suspend from deep inside nested calls, and the functions it calls need no special syntax.
$fiber = new Fiber(function (string $x): string {
$y = Fiber::suspend($x . '!'); // pause, handing a value out
return "got $y";
});
$out = $fiber->start('hi'); // runs until suspend: 'hi!'
$fiber->resume('data'); // suspend() returns 'data'
$fiber->getReturn(); // 'got data'Fibers are cooperative and single-threaded. Only one runs at a time, and a fiber pauses only when it calls Fiber::suspend(). They give no parallelism for CPU work.
What they enable is async I/O. An event loop (the Revolt loop used by AMPHP v3 and ReactPHP's async package) starts many fibers. When one would block on a socket, the library suspends that fiber and registers interest in the socket; when data arrives, the loop resumes it. Application code just writes $response = $client->request($url);, while dozens of requests are in flight concurrently.
Most applications never touch Fiber directly; they use these libraries. Remember the constraints: blocking functions such as sleep(), file_get_contents() on URLs or PDO queries still block the whole process, so you need async-aware drivers, and state shared between fibers needs care just like in any concurrent program.
Example
<?php
// A tiny round-robin scheduler: two "tasks" interleave cooperatively
function task(string $name, int $steps): Fiber {
return new Fiber(function () use ($name, $steps): string {
for ($i = 1; $i <= $steps; $i++) {
echo "$name step $i\n";
Fiber::suspend(); // yield control back to the loop
}
return "$name finished";
});
}
$queue = [task('A', 2), task('B', 3)];
foreach ($queue as $f) $f->start(); // A step 1, B step 1
while ($queue) {
$f = array_shift($queue);
$f->resume();
if ($f->isTerminated()) echo $f->getReturn(), "\n";
else $queue[] = $f;
}
// A step 2, B step 2, A finished, B step 3, B finishedRemember
- A Fiber can suspend from anywhere in its call stack and be resumed later
- Fibers are cooperative and single-threaded: concurrency, not parallelism
- Event loops like Revolt use Fibers to make async I/O look synchronous
Watch out for
- Calling blocking functions (sleep, PDO) inside an async app, which stalls every fiber.