Materialising a generator with iterator_to_array preserves keys by default, and a generator that yields without a key restarts its counter on every inner traversal — so a nested yield loses most of its elements.
function rows(array $files) {
foreach ($files as $file) {
foreach (readLines($file) as $line) { // keys restart per file
yield $line;
}
}
}
count(iterator_to_array(rows($files))); // 40 — the last file only
count(iterator_to_array(rows($files), false)); // 1,200 — all of them
The second argument is preserve_keys and defaults to true, which is the wrong default for almost every generator that composes others. Passing false reindexes and keeps everything. The failure is silent and proportional to how much the data overlaps, so it usually appears as an import that processes suspiciously few records and reports success.