Understanding PHP Coroutines: Generators, Fibers, and Real‑World Use Cases

This article explains what coroutines are, how PHP implements them with Generators and Fibers, compares asymmetric and symmetric designs, shows practical code examples, and outlines scenarios where coroutines improve state handling, lazy iteration, and cooperative multitasking in backend applications.

Open Source Tech Hub
Open Source Tech Hub
Open Source Tech Hub
Understanding PHP Coroutines: Generators, Fibers, and Real‑World Use Cases

What Is a Coroutine?

A coroutine is a function that can pause its execution and later resume, returning a value each time it suspends while preserving its internal state between pauses.

Pausing and Resuming

When a coroutine runs, it voluntarily yields control back to the surrounding code. The surrounding code must explicitly call resume (or an equivalent) to continue the coroutine.

Note: After a coroutine is suspended, other code can continue to run and the program may finish without ever resuming the coroutine.

Return and Receive Values

Each pause can act like a return statement, optionally providing a value. When resumed, a coroutine can also receive a value, making the interaction bidirectional.

Coroutine Types

Coroutines can be asymmetric (control returns only to the caller) or symmetric (control can be passed to any coroutine). The article uses a “potato‑passing” analogy to illustrate the difference.

There are also stackless and stackful coroutines. Stackless coroutines can only suspend at the outermost function, while stackful coroutines can suspend inside nested calls.

Implementing Coroutines with Generators

PHP introduced coroutine support in version 5.5 via Generator. A generator can be started, paused with yield, and resumed with methods such as next(), send(), or throw().

function exampleGenerator(): Generator {
    echo "Started";
    $value = 4;
    yield 1;
    yield;
    yield 3;
    yield $value;
}

$generator = exampleGenerator();
$result = $generator->current(); // int(1)
$generator->next(); // pause, value is null
$generator->next(); // int(3)
$generator->next(); // int(4)

The generator can also receive a value using $generator->send($value), and it can propagate exceptions with $generator->throw($exception).

Using Fibers (PHP 8.1+)

Fibers provide a toolbox for building stackful coroutines. A Fiber instance is created with a callback; the callback can suspend execution with Fiber::suspend() and later be resumed with $fiber->resume().

$coroutine = new Fiber(function () {
    $received = Fiber::suspend('Hello from the Coroutine');
    Fiber::suspend('Received: ' . $received);
});

$result = $coroutine->start(); // "Hello from the Coroutine"
$next   = $coroutine->resume('Hello from the code'); // "Received: Hello from the code"

Fibers support sending values, returning multiple values, and throwing exceptions into the suspended fiber. Because a Fiber has its own call stack, Fiber::suspend() is a static method, while resume() is an instance method.

Practical Use Cases

Coroutines are useful for state machines, CLI wizards, lazy iterators, and cooperative multitasking. Examples include a command‑line questionnaire that yields prompts and receives answers, and a cooking/cleaning simulation that alternates between two Fibers.

$cli = (function () {
    $state = [];
    $state['name'] = yield 'What is your name?';
    $state['age']  = yield 'How old are you?';
    return $state;
})();

$cli->rewind();
while ($cli->valid()) {
    echo $cli->current() . "
";
    $input = trim(fgets(STDIN));
    $cli->send($input);
}
$result = $cli->getReturn();

Generators implement the Iterator interface, making them ideal for lazy data processing that saves memory.

Cooperative Multitasking (Concurrency)

Cooperative multitasking requires an event loop to schedule which coroutine runs next. PHP does not provide a built‑in loop, but libraries such as Revolt and ReactPHP fill this gap.

By alternating between tasks—e.g., cooking steps and cleaning steps—coroutines can keep memory usage low and improve throughput for I/O‑bound workloads.

What’s Next?

The next article will dive into event‑loop libraries, coroutine schedulers, and how to build responsive, non‑blocking PHP applications using tools like Revolt and ReactPHP.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

PHPCoroutinesGeneratorsFibers
Open Source Tech Hub
Written by

Open Source Tech Hub

Sharing cutting-edge internet technologies and practical AI resources.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.