Get "PHP 8 in a Nuthshell" (Now with PHP 8.4)
Amit Merchant

Amit Merchant

A blog on PHP, JavaScript, and more

A practical example of using Fibers in PHP

Extending my previous article on the introduction to Fibers, in this article, we’re going to see a practical example of using Fibers in PHP which might help you understand the concept better.

First, let me show you the code.

echo "Main thread started.\n";

function fetchData($url) {
    $response = file_get_contents($url);
    return $response;
}

$fibers = [];

// Create fibers for multiple asynchronous tasks.
$fibers[] = new Fiber(function() { 
    $response = fetchData("https://api.npoint.io/d96cfc702c24a2992c41"); 
    $value = Fiber::suspend($response);
    print_r($value . "\n");
});

$fibers[] = new Fiber(function() { 
    $response = fetchData("https://api.npoint.io/c116605fac1cb2b75fe9"); 
    $value = Fiber::suspend($response);
    print_r($value . "\n");
});

$fibers[] = new Fiber(function() { 
    $response = fetchData("https://api.npoint.io/327efbf48fbb524bef09"); 
    $value = Fiber::suspend($response);
    print_r($value . "\n");
});

$captureResponseOnSuspension = [];

// Start all fibers.
foreach ($fibers as $i => $fiber) {
    echo "Fiber $i started.\n";
    $captureResponseOnSuspension[$i] = $fiber->start();
}

// Resume all fibers.
foreach ($fibers as $i => $fiber) {
    echo "Fiber $i resumed.\n";
    $fiber->resume($captureResponseOnSuspension[$i]);
}

echo "Main thread done.\n";

// Main thread started.
// Fiber 0 started.
// Fiber 1 started.
// Fiber 2 started.

// Fiber 0 resumed.
// {"why":["data1"],"what":"a simple JSON data store"}
// Fiber 1 resumed.
// {"why":["data2"],"what":"a simple JSON data store"}
// Fiber 2 resumed.
// {"why":["data3"],"what":"a simple JSON data store"}
// Main thread done.

Let’s break down the code above.

We first define a function called fetchData() which is responsible for fetching data from a given URL. This function is going to be used by our fibers to fetch data from the given URLs.

Next, we define an array called $fibers which is going to hold all the fibers we’re going to create. We then create three fibers using the new Fiber() constructor and pass an anonymous function to it which is going to be executed by the fiber.

Inside the anonymous function, we call the fetchData() function and pass the URL to it. The fetchData() function returns the response from the given URL which we then suspend using the Fiber::suspend() method. This method suspends the fiber and returns the value passed to it. We then print the response to the console which will be printed when the fiber is resumed.

$fibers[] = new Fiber(function() { 
    $response = fetchData("https://api.npoint.io/d96cfc702c24a2992c41"); 
    $value = Fiber::suspend($response);
    // This will be printed when the fiber is resumed.
    print_r($value . "\n");
});

We then create another array called $captureResponseOnSuspension which is going to hold the suspended response from the fibers. And in one of the loops, we start all the fibers using the Fiber::start() method and capture the suspended response in the $captureResponseOnSuspension array. This will have the responses from all the fibers when they were suspended.

// Start all fibers.
foreach ($fibers as $i => $fiber) {
    echo "Thread $i started.\n";
    $captureResponseOnSuspension[$i] = $fiber->start();
}

Essentially, this loop will start all the fibers all at once and suspend them.

In the next loop, we resume all the fibers using the Fiber::resume() method and pass the suspended response to it. This will resume the fibers consecutively and pass the suspended response to the fiber which we can then use inside the fiber.

// Resume all fibers.
foreach ($fibers as $i => $fiber) {
    echo "Thread $i resumed.\n";
    $fiber->resume($captureResponseOnSuspension[$i]);
}

As you can tell, this example demonstrates the asynchronous nature of fibers where you can start multiple fibers at once and resume later when you need them.

Remember, PHP fibers are cooperative, so they don’t run in true parallelism like traditional threads, but they can still simulate concurrent execution within a single thread.

Learn the fundamentals of PHP 8 (including 8.1, 8.2, 8.3, and 8.4), the latest version of PHP, and how to use it today with my new book PHP 8 in a Nutshell. It's a no-fluff and easy-to-digest guide to the latest features and nitty-gritty details of PHP 8. So, if you're looking for a quick and easy way to PHP 8, this is the book for you.

Like this article?

Buy me a coffee

👋 Hi there! I'm Amit. I write articles about all things web development. You can become a sponsor on my blog to help me continue my writing journey and get your brand in front of thousands of eyes.

Comments?