Master PHP generators for memory-efficient lazy sequences, yield from for generator delegation, generators as coroutines (two-way communication with send()), PHP 8.1 Fibers for cooperative multitasking, and practical applications: streaming large datasets, infinite sequences, and async-style task switching.
Background
A generator function returns a Generator object when called. It runs lazily — code executes only when you call next() or iterate. yield pauses execution and returns a value; send($value) resumes it and injects a value. This is the basis of coroutines. PHP 8.1 Fibers are lower-level coroutines with an explicit stack — they are the building block that async frameworks (Revolt, ReactPHP 3) use to implement non-blocking I/O without threads.
💡 Generators are pull-based; send() makes them push-based. Normally you pull values out of a generator via foreach or ->current()/->next(). With send($value), you push a value into the generator — it resumes from the last yield, and $value = yield ... receives your input. This two-way channel is what makes generators coroutines. Symfony's Process component and Guzzle use this for async streaming.