Lay András Lay András - 1 month ago 15
PHP Question

PHP generator yield the first value, then iterate over the rest

I have this code:

<?php

function generator() {
yield 'First value';
for ($i = 1; $i <= 3; $i++) {
yield $i;
}
}

$gen = generator();

$first = $gen->current();

echo $first . '<br/>';

//$gen->next();

foreach ($gen as $value) {
echo $value . '<br/>';
}


This outputs:

First value
First value
1
2
3


I need the 'First value' to yielding only once. If i uncomment $gen->next() line, fatal error occured:

Fatal error: Uncaught exception 'Exception' with message 'Cannot rewind a generator that was already run'

How can I solve this?

Answer

The problem is that the foreach try to reset (rewind) the Generator. But rewind() throws an exception if the generator is currently after the first yield.

So you should avoid the foreach and use a while instead

$gen = generator();

$first = $gen->current();

echo $first . '<br/>';
$gen->next();

while ($gen->valid()) {
    echo $gen->current() . '<br/>';
    $gen->next();
}