A Fiber (PHP 8.1) is a function with its own call stack that can pause anywhere, even deep inside nested calls. Fiber::suspend() hands a value out, and resume() sends one back in, the same two-way traffic as a generator's yield and send() (Advanced Generators). A generator, however, can pause only in its own body.
<?php
$fiber = new Fiber(function (string $greeting): string {
$reply = Fiber::suspend("got $greeting"); // hand a value out, wait for one back
echo "fiber resumed with: $reply\n";
return 'done';
});
echo 'main: ', $fiber->start('hello'), "\n"; // runs the fiber up to its suspend
$fiber->resume('abc');
echo 'returned: ', $fiber->getReturn(), "\n";
$t0 = hrtime(true); // but a blocking call blocks everything
foreach (range(1, 3) as $i) (new Fiber(fn () => sleep(1)))->start();
printf("three fibers calling sleep(1): %.2f s\n", (hrtime(true) - $t0) / 1e9);Output
main: got hello fiber resumed with: abc returned: done three fibers calling sleep(1): 3.00 s
Fibers are cooperative: one runs at a time and nothing preempts it. They are pausable stacks, not threads or non-blocking I/O, so three fibers calling sleep(1) take three seconds. They pay off when an event loop resumes them as I/O completes, and libraries such as AMPHP create them for you.