As of 7.3, the behavior of a generator in a foreach loop depends on whether or not it expects to receive data. Relevant if you are experiencing "skips".
<?php
class X implements IteratorAggregate {
public function getIterator(){
yield from [1,2,3,4,5];
}
public function getGenerator(){
foreach ($this as $j => $each){
echo "getGenerator(): yielding: {$j} => {$each}\n";
$val = (yield $j => $each);
yield; echo "getGenerator(): received: {$j} => {$val}\n";
}
}
}
$x = new X;
foreach ($x as $i => $val){
echo "getIterator(): {$i} => {$val}\n";
}
echo "\n";
$gen = $x->getGenerator();
foreach ($gen as $j => $val){
echo "getGenerator(): sending: {$j} => {$val}\n";
$gen->send($val);
}
?>
getIterator(): 0 => 1
getIterator(): 1 => 2
getIterator(): 2 => 3
getIterator(): 3 => 4
getIterator(): 4 => 5
getGenerator(): yielding: 0 => 1
getGenerator(): sending: 0 => 1
getGenerator(): received: 0 => 1
getGenerator(): yielding: 1 => 2
getGenerator(): sending: 1 => 2
getGenerator(): received: 1 => 2
getGenerator(): yielding: 2 => 3
getGenerator(): sending: 2 => 3
getGenerator(): received: 2 => 3
getGenerator(): yielding: 3 => 4
getGenerator(): sending: 3 => 4
getGenerator(): received: 3 => 4
getGenerator(): yielding: 4 => 5
getGenerator(): sending: 4 => 5
getGenerator(): received: 4 => 5