Em 2012-10-10 15:52, Tjerk Meesters escreveu:
Sent from my iPhone
On 10 Oct, 2012, at 6:39 PM, Nicolai Scheer
<nicolai.sch...@gmail.com> wrote:
Hi again!
Thanks for your help an comments on the issue.
cataphract commented on the stream_get_line behaviour (returning
false
when used on an empty file) on the bug report page.
I do agree that reading on an empty file can be considered an error
thus returning false, because there's nothing to read.
Unfortunately, and that's why we stumbled upon this in the first
place, feof does not return true when opening an empty file.
I did not have a look at the internals, but my guess is that feof
just
does not return true because no one did a read on the file handle
yet.
To my mind if would be sensible to return true using feof on an
empty
file, so that one does not actually try a read...
That wouldn't be right. Technically the EOF should be discovered, not
deduced from other information like stat(). Also, some streams don't
support reporting an appropriate size.
What do you think?
I second what Mr. Meesters has said. The end-of-file indicator should
be discovered. That's how stdio works, which is what PHP's function is
modeled after. There's nothing wrong about the indicator being set in a
read call that returned no data, be it because the file is empty or
because the read before just happened to read all the data left.
Before some recent bug fixes, the successive return values would depend
somewhat on chance. bool(false) would only be returned after the
end-of-file had been discovered. So if the last read had read all the
data but had not found eof, then the next call would return an empty
string. But if it had (the most common scenario), it would return false.
This ambiguity, which is problematic mostly because stream_get_line()
strips off the delimiter, has been eliminated. The only one left is that
you cannot tell whether the input stream ends with the delimiter or not:
$ php -r '$fd = fopen("php://temp", "r+"); fwrite($fd, "aa");
rewind($fd); var_dump(stream_get_line($fd, 10, "MM"),
stream_get_line($fd, 10, "MM"));'
string(2) "aa"
bool(false)
$ php -r '$fd = fopen("php://temp", "r+"); fwrite($fd, "aaMM");
rewind($fd); var_dump(stream_get_line($fd, 10, "MM"),
stream_get_line($fd, 10, "MM"));'
string(2) "aa"
bool(false)
Finally, what I suggest is that use stream_get_line() in the same way
that's recommended for fgets():
while (($buffer = stream_get_line($handle, 8192, "MM")) !== false)
{
if (strlen($buffer) == 8192) {
//You may consider this an error
}
echo $buffer;
}
If you're using non-blocking sockets, stream_get_line() may return
false temporarily. In those cases, you may want to do something like:
//stream_get_line() will return false if the stream is temporarily
out
//of data, even if there's some data buffered, as long that
buffered data
//is less than the maxsize you specify and it doesn't contain the
delimiter
do {
//call stream_select() here to wait to for data
while (($buffer = stream_get_line($handle, 8192, "MM")) !==
false) {
if (strlen($buffer) == 8192) {
//You may consider this an error
}
echo $buffer;
}
} while (!feof($handle))
--
Gustavo Lopes
--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php