Fiber-Based Task Scheduler
debt(d7/e5/b7/t7)
Closest to 'only careful code review or runtime testing' (d7). The term's detection_hints explicitly state automated=no, and the code pattern (manual Fiber::suspend/resume coordination without event loop abstraction) requires manual inspection. No static analysis tool can reliably detect blocking I/O inside Fibers or missing suspend() calls — these issues manifest only at runtime under load or through careful code review.
Closest to 'touches multiple files / significant refactor in one component' (e5). The quick_fix recommends adopting Amp v3 or ReactPHP's scheduler abstraction instead of rolling your own. Migrating from manual Fiber coordination to a framework's event loop abstraction requires refactoring I/O handling across multiple files within the async component, but doesn't necessarily require architectural rework of the entire application.
Closest to 'strong gravitational pull' (b7). Applies_to shows this is limited to cli/queue-worker contexts (not web), but within those contexts, choosing a Fiber scheduler shapes every async operation. The concurrency model (cooperative multitasking, single-threaded) imposes constraints on all code that runs within it — no blocking I/O anywhere, exception handling patterns, CPU-bound work must be offloaded. Every change in the async subsystem must respect the scheduler's constraints.
Closest to 'serious trap' (t7). The misconception field explicitly states developers believe 'PHP Fibers provide parallel execution' when they actually provide concurrency (interleaved I/O) not parallelism (simultaneous CPU). This contradicts how similar concepts (threads, goroutines) work in other languages where concurrency primitives often do enable parallelism. Common mistakes reinforce this: using Fibers for CPU-bound work, blocking I/O inside Fibers — both stem from the parallel execution misconception.
Also Known As
TL;DR
Explanation
PHP Fibers (8.1) are stackful coroutines — a Fiber can suspend itself with Fiber::suspend(), returning control to the caller, and be resumed later with $fiber->resume(). A scheduler maintains a queue of Fibers and runs each until it suspends or completes. Combined with non-blocking I/O (event loops like ReactPHP/Revolt), this enables genuine concurrent I/O in a single PHP thread. This is the foundation of async PHP frameworks and how libraries like Amp v3 implement their concurrency model.
Common Misconception
Why It Matters
Common Mistakes
- Blocking I/O inside a Fiber — blocks the entire scheduler, defeating concurrency.
- Not calling Fiber::suspend() when waiting for I/O — the Fiber monopolises the scheduler.
- Creating Fibers for CPU-bound work — they share the same thread; use separate processes instead.
- Not handling Fiber exceptions — uncaught exceptions in a Fiber terminate it silently.
Code Examples
// Blocking I/O inside Fiber — no concurrency gained:
$fiber = new Fiber(function(): void {
$data = file_get_contents('https://api.example.com/data'); // BLOCKS!
Fiber::suspend($data); // Too late — already waited synchronously
});
// Cooperative scheduler with non-blocking I/O:
$scheduler = new SplQueue();
$addTask = function(Fiber $fiber) use ($scheduler) {
$scheduler->enqueue($fiber);
};
// Run scheduler:
while (!$scheduler->isEmpty()) {
$fiber = $scheduler->dequeue();
if (!$fiber->isStarted()) $fiber->start();
elseif ($fiber->isSuspended()) $fiber->resume();
if ($fiber->isSuspended()) $scheduler->enqueue($fiber); // Re-queue
}
// Task: suspend at I/O point, resume when ready:
$task = new Fiber(function() use ($loop): void {
$promise = $loop->httpGet('https://api.example.com');
$data = Fiber::suspend($promise); // Suspend — scheduler runs other tasks
echo $data;
});