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

search for in the

stream_get_meta_data> <stream_get_filters
Last updated: Fri, 03 Oct 2008

view this page in

stream_get_line

(PHP 5)

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

説明

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

最大 length バイトの、 handle で指定されたリソースから読み込んだデータ を返します。読み込みは、length バイト読まれたか、 ending で指定された文字列がストリームに見つかった か (この文字列は返値に 含まれません)、あるいは EOF に達したとき、いずれかの条件のもとで停止します。

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

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

fread()fgets() および fgetc() も参照ください。



stream_get_meta_data> <stream_get_filters
Last updated: Fri, 03 Oct 2008
 
add a note add a note User Contributed Notes
stream_get_line
amoo_miki at yahoo dot com
19-Aug-2008 07: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 12: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 05: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 09: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 11: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, 03 Oct 2008
 
 
show source | credits | sitemap | contact | advertising | mirror sites