PHP - PHP Generators and the yield Keyword — Detailed Explanation
PHP generators are a powerful feature used to iterate over data efficiently, especially when working with large datasets. Instead of loading all data into memory at once (as arrays do), generators allow you to produce values one at a time, only when needed. This approach significantly reduces memory usage and improves performance in many scenarios.
What is a Generator?
A generator is a special type of function in PHP that uses the yield keyword instead of return. When a generator function is called, it does not execute immediately. Instead, it returns an object of type Generator, which can be iterated using a loop like foreach.
Each time the generator is iterated, it resumes execution from where it left off and yields the next value.
Basic Syntax and Working
A simple example:
function numbers() {
yield 1;
yield 2;
yield 3;
}
foreach (numbers() as $num) {
echo $num . "\n";
}
Output:
1
2
3
Explanation:
-
The function
numbers()does not return all values at once. -
Each
yieldpauses execution and sends a value to the loop. -
When the loop requests the next value, execution resumes from the next
yield.
How Generators Work Internally
When a generator function is called:
-
PHP creates a
Generatorobject. -
Execution starts only when iteration begins.
-
Each
yieldsaves the current state (variables, position). -
The function pauses and resumes on the next iteration.
This behavior is called lazy evaluation, meaning values are generated only when required.
Generators vs Arrays
Consider handling a large dataset:
Using an array:
function getNumbers() {
return range(1, 1000000);
}
This creates an array with 1 million elements in memory.
Using a generator:
function getNumbers() {
for ($i = 1; $i <= 1000000; $i++) {
yield $i;
}
}
Here:
-
Only one value exists in memory at a time.
-
Memory usage is minimal regardless of dataset size.
Yield with Keys
Generators can also return key-value pairs:
function userData() {
yield "name" => "Teena";
yield "role" => "Developer";
}
foreach (userData() as $key => $value) {
echo "$key: $value\n";
}
Yield from (Delegation)
The yield from keyword allows one generator to delegate to another:
function gen1() {
yield 1;
yield 2;
}
function gen2() {
yield from gen1();
yield 3;
}
This avoids manually looping through another generator.
Returning Values from Generators
Generators can return a final value using return, which is separate from yield.
function test() {
yield 1;
yield 2;
return "Done";
}
The return value can be accessed using:
$gen = test();
foreach ($gen as $value) {
echo $value;
}
echo $gen->getReturn();
Real-World Use Cases
-
Reading large files line by line
Instead of loading an entire file into memory, a generator can read and yield one line at a time. -
Processing database records
Fetching rows one by one instead of loading the full result set. -
API data streaming
Handling paginated API responses efficiently. -
Infinite sequences
Generators can produce values indefinitely without memory issues.
Advantages
-
Very low memory consumption
-
Efficient handling of large datasets
-
Cleaner and more readable iteration logic
-
Supports lazy evaluation
-
Useful for streaming and pipelines
Limitations
-
Cannot rewind easily like arrays
-
Slightly more complex debugging
-
Not suitable when all data must be accessed at once
Summary
PHP generators provide a modern and efficient way to work with sequences of data. By using the yield keyword, they allow functions to behave like iterators, producing values on demand rather than all at once. This makes them especially useful in performance-critical applications where memory efficiency matters.