百科狗-知识改变命运!
--

stream_get_line() - php 流数据函数stream

梵高1年前 (2023-11-21)阅读数 20#技术干货
文章标签字符串

stream_get_line()

(PHP 5, PHP 7)

从资源流里读取一行直到给定的定界符

说明

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

从给定的资源流里读取一行。

当读取到$length个字节数就结束,或者当在读取的字符串中发现$ending(包含到返回值里)也结束,又或者遇到了EOF也结束(总之以上条件中哪个先出现就以哪个为准)。

这个函数与fgets()几乎是相同的,唯一的区别是在这个函数里面允许指定行尾的定界符,而不是使用标准的n,r 还有rn ,并且返回值中包含定界符。(翻译注:也可以把n 等作为定界符传入$ending)

参数

$handle

一个有效的文件句柄。

$length

需要从句柄里读取的字节数。

$ending

可选参数,字符串定界符。

返回值

返回一个字符串,该字符串的内容根据$length字节数从$handle里读取。

stream_get_line() - php 流数据函数stream

如果发生错误,则返回FALSE.

参见

  • fread() 读取文件(可安全用于二进制文件)
  • fgets() 从文件指针中读取一行
  • fgetc() 从文件指针中读取字符
fgets is faster but stream_get_line is more useful in a tcp server scripts.
when fgets reads some bytes from socket, where EOF is reached, it returns bool(false) same as stream_get_line
BUT if remote client drops connection, and server script will try to read some data with function fgets, function will return bool(false), and stream_get_line will return string(0) ""
so you can detect remote client disconnection with stream_get_line, and cannot with fgets
If you are specifying the 3rd optional "ending" parameter as a string which is more than one character and actually find that the line returned by the function sometimes contains this "ending" value it may be related to the following bug, https://bugs.php.net/bug.php?id=63240
Our server was running 5.3.18 and when we upgraded to 5.3.20 it worked fine, I believe this was fixed in 5.3.19 though.
WARNING:
Specifying a length of 0 does NOT give you an infinite length, contrary to what the documentation might suggest. Instead, setting a length of 0 just makes the function default to a length of 8192. To be precise, it gets the value PHP_SOCK_CHUNK_SIZE (8192) in ext/standard/streamsfuncs.c.
So, let's say you're trying to read ALL data until you reach a "\x03" (decimal 3) byte. How do you GUARANTEE that this is the case? Well, there's no way! The only thing you can do stream_get_lin() into a "master" string, then fseek() backwards by 1 character, then fgetc() and verify that it's "\x03". If you don't see a "\x03", it means that stream_get_line() has aborted after 8192 bytes and before hitting "\x03", and you'll have to call it again. Keep appending the return values to a "master" string until you hit a "\x03" or EOF... That's the ONLY way to properly build a string that contains EVERYTHING until the character you're looking for.
I have been struggling with the problem that stream_get_line() sometimes reads too much when the 3rd parameter is used (and the 3rd parameter has a length greater than 1), so $ending is actually contained in the data returned (https://bugs.php.net/bug.php?id=63240).
I don't have the option of upgrading my PHP version but it seems that a workaround can be to insert:
  fseek($fp, ftell($fp));
just before calling stream_get_line().
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: 
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. 
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:

vs. 
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
test
-------------------------------------------------------------
The code:

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>test 
into $out.

鹏仔微信 15129739599 鹏仔QQ344225443 鹏仔前端 pjxi.com 共享博客 sharedbk.com

免责声明:我们致力于保护作者版权,注重分享,当前被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理!邮箱:344225443@qq.com)

图片声明:本站部分配图来自网络。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

内容声明:本文中引用的各种信息及资料(包括但不限于文字、数据、图表及超链接等)均来源于该信息及资料的相关主体(包括但不限于公司、媒体、协会等机构)的官方网站或公开发表的信息。部分内容参考包括:(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供参考使用,不准确地方联系删除处理!本站为非盈利性质站点,本着为中国教育事业出一份力,发布内容不收取任何费用也不接任何广告!)