Bug #65235 [Opn->Nab]: Unexpected behavior of the "yield"
Edit report at https://bugs.php.net/bug.php?id=65235&edit=1
ID: 65235
Updated by: nikic@php.net
Reported by: shooric_ at mail dot ru
Summary: Unexpected behavior of the "yield"
-Status: Open
+Status: Not a bug
Type: Bug
Package: Scripting Engine problem
Operating System: Linux3.2.0-49
PHP Version: 5.5.0
Block user comment: N
Private report: N
New Comment:
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.
Previous Comments:
------------------------------------------------------------------------
[2013-07-10 14:25:31] 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
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=65235&edit=1
Thread (3 messages)