PHP - Asynchronous Programming with Fibers in PHP
Asynchronous programming is a programming technique that allows a program to perform multiple tasks without waiting for one task to finish before starting another. In traditional PHP applications, code is executed sequentially. Each statement must complete before the next one begins. While this approach is simple and effective for many web applications, it can become inefficient when a program spends significant time waiting for external resources such as databases, APIs, file systems, or network connections.
To address this limitation, PHP 8.1 introduced Fibers, a feature that enables cooperative multitasking within a PHP application. Fibers allow developers to pause the execution of one task and resume another task without creating multiple operating system threads. This makes it possible to write asynchronous code in a way that looks and behaves like normal synchronous code.
What is a Fiber?
A Fiber is a lightweight execution unit that has its own call stack. Unlike functions, which execute from start to finish once called, a Fiber can pause its execution at a specific point and later continue from exactly where it stopped.
Fibers provide complete control over execution flow. They allow developers to manually suspend and resume tasks, making asynchronous programming more organized and easier to understand.
Unlike threads, Fibers do not run simultaneously on different CPU cores. Instead, they execute one at a time, with the application deciding when to switch between them. This process is called cooperative multitasking.
Why Were Fibers Introduced?
Before Fibers, PHP developers relied on callbacks, generators, or third-party libraries to implement asynchronous behavior. These methods often made code difficult to read and maintain.
Fibers solve several common problems:
-
Simplify asynchronous programming.
-
Reduce deeply nested callback functions.
-
Improve code readability.
-
Enable modern asynchronous frameworks.
-
Support efficient handling of multiple I/O operations.
Fibers are especially useful in applications that communicate with multiple external services simultaneously.
How Fibers Work
A Fiber follows a simple lifecycle.
-
A Fiber object is created.
-
The Fiber starts executing.
-
It performs some operations.
-
The Fiber suspends itself when waiting for another operation.
-
Another Fiber or task executes.
-
The suspended Fiber resumes from its previous position.
-
The Fiber finishes execution.
The Fiber does not restart from the beginning after resuming. It continues from the exact instruction where it was suspended.
Fiber Lifecycle
1. Creation
A Fiber is created using the Fiber class.
$fiber = new Fiber(function () {
echo "Fiber Started";
});
At this stage, the Fiber exists but has not executed any code.
2. Starting
Execution begins using the start() method.
$fiber->start();
The Fiber starts executing from the beginning.
3. Suspension
A Fiber can pause its execution.
Fiber::suspend("Waiting");
Execution stops temporarily and returns control to the caller.
4. Resuming
The paused Fiber continues execution.
$fiber->resume();
Execution resumes from the exact suspension point.
5. Termination
Once all statements execute, the Fiber automatically terminates.
Basic Fiber Example
<?php
$fiber = new Fiber(function () {
echo "Step 1\n";
Fiber::suspend();
echo "Step 2\n";
});
$fiber->start();
echo "Main Program\n";
$fiber->resume();
?>
Output
Step 1
Main Program
Step 2
Explanation
The Fiber starts and prints "Step 1". It then suspends itself. Control returns to the main program, which prints "Main Program". When resume() is called, the Fiber continues and prints "Step 2".
Passing Values During Suspension
Fibers can exchange information while suspending and resuming.
<?php
$fiber = new Fiber(function () {
$value = Fiber::suspend("Waiting");
echo "Received: $value";
});
$result = $fiber->start();
echo $result;
$fiber->resume("Completed");
?>
Output
Waiting
Received: Completed
The Fiber returns "Waiting" when suspended. When resumed, it receives "Completed" as input.
Multiple Fibers
An application may execute multiple Fibers.
$fiber1 = new Fiber(function () {
echo "Task A\n";
Fiber::suspend();
echo "Task A Finished\n";
});
$fiber2 = new Fiber(function () {
echo "Task B\n";
});
$fiber1->start();
$fiber2->start();
$fiber1->resume();
Output
Task A
Task B
Task A Finished
Each Fiber executes independently while sharing the same process.
Practical Use Cases
API Requests
Suppose an application retrieves weather data, stock prices, and news headlines.
Without Fibers:
-
Request weather.
-
Wait.
-
Request stocks.
-
Wait.
-
Request news.
-
Wait.
With Fibers:
-
Start all requests.
-
Suspend each while waiting.
-
Resume them as responses arrive.
This reduces idle waiting time and improves responsiveness.
File Operations
An application reading multiple large files can suspend processing while waiting for disk access and continue with other tasks.
Database Queries
Applications communicating with multiple databases can switch between queries instead of waiting for each query to complete.
Chat Servers
Real-time messaging applications often need to handle many client connections simultaneously. Fibers help manage these connections efficiently.
Background Processing
Tasks such as image resizing, email sending, and report generation can pause while waiting for resources and allow other tasks to continue.
Advantages of Fibers
Cleaner Code
Fibers eliminate complex callback chains, making programs easier to read and maintain.
Better Resource Utilization
Applications spend less time idle while waiting for slow operations to complete.
Improved Scalability
Servers handling many client requests can manage more operations efficiently by switching between waiting tasks.
Easier Error Handling
Since asynchronous code resembles synchronous code, exceptions and error handling become simpler.
Lightweight Execution
Fibers consume much less memory than operating system threads, allowing many Fibers to exist within a single process.
Limitations of Fibers
Not Parallel Execution
Fibers do not execute tasks simultaneously on multiple CPU cores. They run cooperatively within a single thread.
Manual Scheduling
PHP does not automatically decide when to switch between Fibers. The application or framework must control suspension and resumption.
Best for I/O Tasks
Fibers provide the greatest benefit for input/output operations such as network communication, file access, and database interactions. CPU-intensive calculations still execute sequentially.
Requires PHP 8.1 or Later
Fibers are unavailable in earlier PHP versions.
Fibers vs Threads
| Feature | Fibers | Threads |
|---|---|---|
| Execution Model | Cooperative | Preemptive |
| Memory Usage | Very Low | Higher |
| Runs on Multiple CPU Cores | No | Yes |
| Context Switching | Controlled by Application | Controlled by Operating System |
| Complexity | Lower | Higher |
| Synchronization Issues | Minimal | Common |
| Suitable for I/O Tasks | Excellent | Good |
Fibers in Modern PHP Frameworks
Several asynchronous PHP frameworks and libraries use Fibers internally to simplify asynchronous programming and improve performance. These include:
-
Revolt Event Loop
-
Amp
-
OpenSwoole
-
ReactPHP (with Fiber support through modern integrations)
These frameworks allow developers to build high-performance web servers, REST APIs, WebSocket applications, real-time dashboards, and background processing systems using asynchronous programming techniques.
Best Practices
-
Use Fibers primarily for I/O-bound operations rather than CPU-intensive tasks.
-
Keep Fiber logic focused on a single responsibility.
-
Properly handle exceptions within Fibers to prevent unexpected termination.
-
Avoid creating unnecessary Fibers, as excessive switching can reduce efficiency.
-
Combine Fibers with an event loop when developing highly concurrent applications.
-
Ensure the application resumes suspended Fibers appropriately to avoid stalled execution.
Conclusion
Fibers are one of the most significant additions to modern PHP, enabling developers to write asynchronous code that is clean, structured, and easy to maintain. By allowing execution to pause and resume without relying on complex callbacks or heavyweight threads, Fibers make it possible to build scalable applications capable of efficiently handling multiple tasks, especially those involving network requests, file operations, and database interactions. As asynchronous programming continues to gain importance in modern web development, understanding Fibers has become an essential skill for PHP developers building high-performance applications.