downloads | documentation | faq | getting help | mailing lists | licenses | wiki | reporting bugs | php.net sites | links | conferences | my php.net

search for in the

stream_get_meta_data> <stream_get_filters
Last updated: Fri, 13 Nov 2009

view this page in

stream_get_line

(PHP 5)

stream_get_line指定されたデリミタの位置までのデータを一行分としてストリームから読み込む

説明

string stream_get_line ( resource $handle , int $length [, string $ending ] )

指定したハンドルから一行取得します。

読み込みは、length バイト読まれたか、 ending で指定された文字列がストリームに見つかった か (この文字列は返値に 含まれません)、あるいは EOF に達したとき、のうち一番最初に遭遇したところで停止します。

この関数は fgets() とほとんど同一ですが、 \n や \r 、\r\n といった一般的な文字列以外を行末を示すデリミタ として指定できる点で、またデリミタ自体を返値に 含まない 点で異なります。

パラメータ

handle

有効なファイルハンドル。

length

ハンドルから読み込むバイト数。

ending

オプションのデリミタ文字列。

返り値

最大 length バイトの、 handle で指定されたリソースから読み込んだデータを返します。

エラーが発生した際には、FALSE を返します。

参考

  • fread() - バイナリセーフなファイルの読み込み
  • fgets() - ファイルポインタから 1 行取得する
  • fgetc() - ファイルポインタから1文字取り出す


stream_get_meta_data> <stream_get_filters
Last updated: Fri, 13 Nov 2009
 
add a note add a note User Contributed Notes
stream_get_line
bens at effortlessis dot com
20-Jul-2009 05:36
I've seen posts here and at fgets about stream_get_line() being much faster than fgets. I'm seeing opposite results.

With PHP 5.2.9 (Fedora Core 10) on a dual-core laptop with 2 GB of RAM:

// SCRIPT:
$fp=fopen("php://stdin","r");
// uncomment ONE of the following two lines:
// while($line=stream_get_line($fp,65535,"\n"))
// while ($line = fgets($fp, 65535))
 { 1; }
fclose($fp);

// SHELL PROMPT:
$ time yes "This is a test line" | head -1000000 | php -q SCRIPT

with stream_get_line() enabled, it takes 25 seconds to run. With fgets enabled, it takes 10. I tried it several times and got consistent results within about 1/10 of a second. And stream_get_line() not only doesn't return the limiter (providing no sure way to pass data through including the delimiters) but is also unavailable on PHP4 (which is still commonly used)

So, as far as which is faster, YMMV.
amoo_miki at yahoo dot com
19-Aug-2008 05:34
If the "ending" is a string, there are cases where the function doesn't return the correct value for the first time it is called. Don't be shocked if you find it returning a string value of upto "length" that includes the "ending". (See bug #44607)

If the "ending" is just a single character, the function would always work correctly. ("\n" is a single character)

Temporarily, until this is fixed, the below function can be used:

<?php
function istream_get_line(&$fp, $length, $end) {
   
$current = ftell($fp);
   
$str = fread($fp, $length);
   
$i = strpos($str, $end);
    if (
$i === FALSE) {
        return
$str;   
    } else {
       
fseek($fp, $current + $i + strlen($end));
        return
substr($str, 0, $i);
    }
}
?>
mail at mdijksman dot nl
15-May-2008 10:32
In addition to dante at lorenso dot com:

I was having problems reading the header of a response with stream_get_line, on the Date: part.

<?php
   
// Sometimes took about 2 minutes
   
while (!feof($fp))                                                                                
    {
       
$line = stream_get_line($fp, 1024, "\n");                                                       
               
        if (
strcmp($line, "\r") == 0)                                                               
        {
            break;
        }       
    }        
   
   
// Always takes less than a second
   
while (!feof($fp))                                                                                
    {
       
$line = fgets($fp, 1024);
               
        if (
strcmp($line, "\r\n") == 0)                                                               
        {
            break;
        }       
    }        
?>

I could find no logic in this, as the stream_get_line sometimes went fast, and sometimes went really slow. In the end I just stopped using stream_get_line and switched to fgets.
Mat Jaggard at Tickets dot com
20-Dec-2007 04:12
I've spent quite a while trying to get stream_get_line to get a chunk encoded html file and to finish correctly at the end so that I can pipeline requests.

This is the function I have come up with.

<?php
   
function getURLContents($url, $ip, $port, $ssl = false, $closeConnection = false)
    {
        if (
$ssl)
           
$ssl = 'ssl://';
        else
           
$ssl = '';
       
$fp = pfsockopen($ssl.$ip, $port, $errno, $errstr, MAX_TIME_TO_START_CONNECTION);
        if (
$fp)
        {
           
$out 'GET '.$url." HTTP/1.1\r\n";
           
$out .= 'Host: '.$ip.':'.$port."\r\n";
            if (
$closeConnection)
               
$out .= "Connection: close\r\n";
            else
               
$out .= "Connection: keep-alive\r\n";
           
$out .= "\r\n";
            if (!
fwrite($fp, $out))
            {
                echo
'Problem writing to socket, opening a new connection.';
               
fclose($fp);
               
$fp = pfsockopen($ssl.$ip, $port, $errno, $errstr, MAX_TIME_TO_START_CONNECTION);
               
fwrite($fp, $out);
            }
           
$theData = '';
           
$notDone = true;
           
stream_set_blocking($fp, 0);
           
$startTime = time();
           
$lastTime = $startTime;
            while (!
feof($fp) && !$done && (($startTime + MAX_TIME_FOR_THE_RESPONSE) > time()))
            {
               
usleep(100);
               
$theNewData = stream_get_line($fp, 1024, "\n");
               
$theData .= $theNewData;
               
$done = (trim($theNewData) === '0');

            }
        }
        else
        {
            echo
'ERROR CONNECTING TO '.$ip.':'.$port;
            return
false;
        }
        if (
$closeConnection)
           
fclose($fp);
        return
$theData;
    }
?>
dante at lorenso dot com
08-Jun-2006 07:34
My testing has found this function to be dramatically faster than fgets on PHP 5.1.14.  The difference is probably due to how buffering is used internally.  Compare the following:
<?php
// reads 10,000 lines in 27 seconds
while (!feof($handle)) {
   
$line = fgets($handle, 1000000);
}
?>
vs.
<?php
// reads 10,000 lines in 0.5 seconds
while (!feof($handle)) {
   
$line = stream_get_line($handle, 1000000, "\n");
}
?>
18-Apr-2006 09:07
In version 5.0.4 using this funtion and then calling ftell($stream) would give you the position up to but not including the "ending" string.

When I rev'd to PHP version 5.1.2, calling this function then using ftell($stream) would give the position up to AND including the "ending" string

for example, parsing HTTP responses.

The response from apache using curl....
------------------------------------------------------------
HTTP/1.1 200 OK
Date: Tue, 18 Apr 2006 20:54:59 GMT
Server: Apache/1.3.33 (Unix) PHP/5.0.4 mod_ssl/2.8.22 OpenSSL/0.9.7e
X-Powered-By: PHP/5.0.4
Transfer-Encoding: chunked
Content-Type: text/html

<html><body>test</body></html>
-------------------------------------------------------------

The code:

<?php

  $headers
= stream_get_line($in,4096,"\r\n\r\n");

  
fseek ($in,ftell($in)+4);

   while (!
feof($in)){
     
fputs ($out,stream_get_line($in,4096,''));
   }

?>

prior to my 5.0.4 this worked perfectly, trimming the \r\n\r\n section of the HTTP response and seperating the top into the $headers string, and the rest was placed into the file handle $out.

using php 5.1.2, the above code chopps off the first 4 bytes of the HTTP response and puts

l><body>test</body></html>

into $out.

stream_get_meta_data> <stream_get_filters
Last updated: Fri, 13 Nov 2009
 
 
show source | credits | stats | sitemap | contact | advertising | mirror sites