Fibers: Cooperative Concurrency
Fibers let you pause a whole call stack and resume it later — the low-level primitive behind modern async runtimes like ReactPHP and Amp.
A Fiber (PHP 8.1+) is a block of code with its own stack that you can suspend from anywhere deep inside and resume later, passing values in both directions. Where a generator only pauses at its own top level, a Fiber can pause across nested function calls. It's cooperative, not parallel — one thing runs at a time — but it's exactly what event-loop libraries use to make blocking-looking code non-blocking.
Easy example
<?php
$fiber = new Fiber(function(): void {
echo "start\n";
Fiber::suspend(); // pause here
echo "resumed\n";
});
$fiber->start(); // prints 'start', then pauses
echo "outside\n";
$fiber->resume(); // prints 'resumed'You'll rarely write Fibers by hand — you'll use a framework built on them. But understanding the pause/resume model demystifies how async PHP works.
Example
When to use it
- Use a Fiber to implement a cooperative task scheduler that switches between multiple I/O-bound operations without threads.
- Pause a Fiber mid-execution to yield a partial result to the main loop, then resume it with new data.
- Build an async-style HTTP client prototype using Fibers that suspends while waiting for a response.
More examples
Basic Fiber suspend and resume
Fiber::suspend() yields a value to the caller and pauses the whole call stack; resume() sends a value back and continues.
<?php
$fiber = new Fiber(function (): void {
$value = Fiber::suspend('paused at step 1');
echo "Resumed with: $value\n";
Fiber::suspend('paused at step 2');
echo "Final step";
});
$v1 = $fiber->start();
echo "Fiber said: $v1\n"; // paused at step 1
$v2 = $fiber->resume('hello');
echo "Fiber said: $v2\n"; // paused at step 2
$fiber->resume('world'); // Final stepSimple cooperative scheduler
Starting then resuming fibers in rounds interleaves their output, demonstrating cooperative multitasking without OS threads.
<?php
$tasks = [
new Fiber(function (): void {
echo "Task A: step 1\n";
Fiber::suspend();
echo "Task A: step 2\n";
}),
new Fiber(function (): void {
echo "Task B: step 1\n";
Fiber::suspend();
echo "Task B: step 2\n";
}),
];
// Start all fibers
foreach ($tasks as $t) { $t->start(); }
// Resume all fibers
foreach ($tasks as $t) { if (!$t->isTerminated()) { $t->resume(); } }Fiber returning a value
A Fiber can return a final value; getReturn() retrieves it after the fiber's function completes.
<?php
$fiber = new Fiber(function (): int {
$data = Fiber::suspend('ready');
return strlen($data) * 2; // final return value
});
$fiber->start();
$fiber->resume('Hello World');
echo $fiber->getReturn(); // 22
Discussion