Understanding PHP Generators and the yield Keyword
This article explains PHP's Generator feature introduced in version 5.5, demonstrating how the yield keyword enables memory‑efficient iteration, how to implement custom xrange functions, and how to control generators with methods like next, current, valid, send, rewind, and throw.
Since PHP 5.5, the language includes a new feature called Generator (generated as "生成器" in Chinese) that allows developers to create memory‑efficient iterators using the yield keyword.
Traditional iteration often relies on range to build an array and then loops with foreach . For example:
<code>foreach (range(1, 100, 2) as $num) {
echo $num . PHP_EOL;
}</code>While this works, generating large sequences (e.g., one million numbers) can consume excessive memory. A generator solves this by yielding values on demand:
<code>function xrange($start, $limit, $step = 1) {
while ($start <= $limit) {
yield $start;
$start += $step;
}
}</code>Using the generator produces the same output as the previous loop but without storing the entire sequence in memory:
<code>$nums = xrange(1, 100, 2);
while ($nums->valid()) {
echo $nums->current() . "\n";
$nums->next();
}</code>The yield keyword pauses the function, preserving its context, and returns a Generator object. The object's next() method resumes execution until the next yield is encountered; when no further yield appears, the generator is considered finished.
Generators expose several useful methods:
valid() – checks whether the generator has more values.
current() – returns the value yielded most recently.
next() – advances to the next yielded value.
send($value) – injects a value back into the generator, which becomes the result of the yield expression.
key() – when using yield $id => $value , key() returns the identifier ($id) while current() returns the associated value.
rewind() – restarts the generator from the beginning, implicitly called before the first send() .
throw($exception) – throws an exception inside the generator.
Example of sending a value into a generator:
<code>function sum() {
$ret = yield;
echo $ret . PHP_EOL;
}
$sum = sum();
$sum->send('I am from outside.');</code>Another example combines yield with send() to modify the iteration flow:
<code>function xrange($start, $limit, $step = 1) {
while ($start <= $limit) {
$ret = yield $start;
$start += $step;
echo $ret . PHP_EOL;
}
}
$nums = xrange(1, 100, 2);
while ($nums->valid()) {
echo $nums->current() . "\n";
$nums->send($nums->current() + 1);
}</code>In summary, the yield keyword introduced in PHP 5.5 provides a powerful way to implement efficient iterators and even coroutine‑like behavior, reducing memory usage and offering fine‑grained control over data generation.
php中文网 Courses
php中文网's platform for the latest courses and technical articles, helping PHP learners advance quickly.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.