|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2013-07-10 14:25 UTC] shooric_ at mail dot ru
Description:
------------
When you interrupt iterations on "yield" generator via "break" instruction,
generator function does not work out until the end of.
Test script:
---------------
<?php
$filename = '111111.txt';
$h = fopen($filename, 'w+');
for($i = 0; $i < 7; $i++) {
echo 'write: ' . $i . PHP_EOL;
fwrite($h, $i . PHP_EOL);
}
fclose($h);
function file_line_iterator($filename) {
echo 'open file' . PHP_EOL;
$h = fopen($filename, 'r');
while(false !== $line = fgets($h)) {
echo 'yield: ' . $line;
yield $line;
}
echo 'close file' . PHP_EOL;
fclose($h);
}
$k = 0;
foreach(file_line_iterator($filename) as $k => $v) {
echo 'iterate: ' . $v;
if(++$k > 4) {
break;
}
}
echo 'exit' . PHP_EOL;
exit;
Expected result:
----------------
write: 0
write: 1
write: 2
write: 3
write: 4
write: 5
write: 6
open file
yield: 0
iterate: 0
yield: 1
iterate: 1
yield: 2
iterate: 2
yield: 3
iterate: 3
yield: 4
iterate: 4
* close file
exit
Actual result:
--------------
write: 0
write: 1
write: 2
write: 3
write: 4
write: 5
write: 6
open file
yield: 0
iterate: 0
yield: 1
iterate: 1
yield: 2
iterate: 2
yield: 3
iterate: 3
yield: 4
iterate: 4
exit
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Thu Nov 27 00:00:01 2025 UTC |
A generator will only run as far as you run it - that's the whole point of it. If you want to ensure that some piece of code is always run, even if you don't consume the generator to the end, you can use a finally block: function file_line_iterator($filename) { $h = fopen($filename, 'r'); try { while (false !== $line = fgets($h)) { yield $line; } } finally { fclose($h); } } In your particular case this is not necessary as PHP will automatically close the file when the generator is destroyed.