yield from делегує частину генерації іншому генератору чи ітерованому значенню: усі його значення віддаються так, ніби їх видав поточний генератор.
function walk(array $node): Generator
{
yield $node['path'];
foreach ($node['children'] as $child) {
yield from walk($child); // рекурсивний обхід дерева
}
}
foreach (walk($tree) as $path) {
echo $path, PHP_EOL;
}
Працює з генераторами, масивами й будь-яким Traversable.
Повернення значення з генератора: return у генераторі не віддає значення в цикл, а зберігає його як результат - його читають через getReturn() після завершення:
function importRows(iterable $rows): Generator
{
$imported = 0;
foreach ($rows as $row) {
yield $row['id']; // проміжні результати
$imported++;
}
return $imported; // підсумок
}
$gen = importRows($rows);
foreach ($gen as $id) { /* ... */ }
echo $gen->getReturn(); // кількість
А yield from повертає результат делегованого генератора:
$count = yield from importRows($rows);
Пастки:
- Ключі.
yield fromзберігає ключі делегованого джерела. Дваyield fromпо масивах з ключами0, 1, 2дадуть дублікати ключів, іiterator_to_array()перезапише значення. Рішення -iterator_to_array($gen, preserve_keys: false). getReturn()до завершення генератора кидає виняток.- Генератор одноразовий: пройти його вдруге не можна.
Двосторонній обмін: $received = yield $value; разом із $gen->send($data) дозволяє передавати дані в генератор - на цьому будували співпрограми до появи Fibers.