Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:63343 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 25878 invoked from network); 11 Oct 2012 07:59:00 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 11 Oct 2012 07:59:00 -0000 Authentication-Results: pb1.pair.com header.from=glopes@nebm.ist.utl.pt; sender-id=unknown Authentication-Results: pb1.pair.com smtp.mail=glopes@nebm.ist.utl.pt; spf=permerror; sender-id=unknown Received-SPF: error (pb1.pair.com: domain nebm.ist.utl.pt from 193.136.128.22 cause and error) X-PHP-List-Original-Sender: glopes@nebm.ist.utl.pt X-Host-Fingerprint: 193.136.128.22 smtp2.ist.utl.pt Linux 2.6 Received: from [193.136.128.22] ([193.136.128.22:51657] helo=smtp2.ist.utl.pt) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 1C/83-04101-D3C76705 for ; Thu, 11 Oct 2012 03:58:54 -0400 Received: from localhost (localhost.localdomain [127.0.0.1]) by smtp2.ist.utl.pt (Postfix) with ESMTP id 3C7E97000435 for ; Thu, 11 Oct 2012 08:58:50 +0100 (WEST) X-Virus-Scanned: by amavisd-new-2.6.4 (20090625) (Debian) at ist.utl.pt Received: from smtp2.ist.utl.pt ([127.0.0.1]) by localhost (smtp2.ist.utl.pt [127.0.0.1]) (amavisd-new, port 10025) with LMTP id R5g7bgla59rE for ; Thu, 11 Oct 2012 08:58:49 +0100 (WEST) Received: from nebm.ist.utl.pt (unknown [IPv6:2001:690:2100:4::58:1]) by smtp2.ist.utl.pt (Postfix) with ESMTP id D3EF07000430 for ; Thu, 11 Oct 2012 08:58:49 +0100 (WEST) Received: from localhost ([127.0.0.1] helo=nebm.ist.utl.pt) by nebm.ist.utl.pt with esmtp (Exim 4.72) (envelope-from ) id 1TMDfN-0005vo-Ky for internals@lists.php.net; Thu, 11 Oct 2012 08:58:49 +0100 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit Date: Thu, 11 Oct 2012 09:58:49 +0200 To: Organization: =?UTF-8?Q?N=C3=BAcleo_de_Engenharia_Biom=C3=A9dica_do_Insti?= =?UTF-8?Q?tuto_Superior_T=C3=A9cnico?= In-Reply-To: References: Message-ID: X-Sender: glopes@nebm.ist.utl.pt User-Agent: RoundCube Webmail/0.8-rc Subject: Re: [PHP-DEV] =?UTF-8?Q?stream=5Fget=5Fline=20behaviour=20Bug=20?= =?UTF-8?Q?=23=36=33=32=34=30?= From: glopes@nebm.ist.utl.pt (Gustavo Lopes) Em 2012-10-10 15:52, Tjerk Meesters escreveu: > Sent from my iPhone > > On 10 Oct, 2012, at 6:39 PM, Nicolai Scheer > 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