php flush()问题~

在编写php的iframe文件流comet时,需要php不断输出数据,然而不过直接用echo一般根据服务器php.ini的implicit_flush设定(常常为false)是不能在运行中输出的,所以要用到flush()缓存输出函数。比如如下代码:

for($i=0;$i<20;$i++) {
    echo $i;
    flush();
    sleep(1);
}
但是往往服务器并不顺序输出,而是等待一段时间后一次性输出,google一下了解到,这里涉及了ob_flush()、flush()两个函数,ob_* 系列函数是操作PHP本身的输出缓冲区,ob_flush()是把数据从PHP的缓冲中释放出来,flush()是把不在缓冲中的或者说是被释放出来的数据发送到浏览器。即输出的正常流程是:echo->php内部缓存->服务器缓存->浏览器。对应的输出缓存流程是:echo "hello~"->ob_flush()->flush()。所以代码更改为:

for($i=0;$i<20;$i++) {
    echo $i;
    if(ob_get_length()){
        ob_start();
        ob_flush();
        flush();
        ob_end_flush();
    }
    sleep(1);
}
这里增加了一个缓冲区内容长度判断,相关函数参考如下:
  • ob_start : 打开输出缓冲区,当缓冲区激活时,所有来自PHP程序的非文件头信息均不会发送,而是保存在内部缓冲区。
  • 获取缓冲区信息
    • ob_get_contents : 返回内部缓冲区的内容。
    • ob_get_clean : 返回内部缓冲区的内容,并关闭缓冲区。相当于执行 ob_get_contents() and ob_end_clean()
    • ob_get_flush :返回内部缓冲区的内容,并关闭缓冲区,再释放内部缓冲区的内容。相当于ob_end_flush() 并返回内部缓冲区内容
    • ob_get_length :返回内部缓冲区的长度,如果缓冲区未被激活,该函数返回FALSE。
    • ob_get_level: Return the nesting level of the output buffering mechanism
    • ob_get_status: Get status of output buffers
  • 关闭/删除/刷新缓冲
    • ob_clean :删除内部缓冲区的内容,但不关闭缓冲区,也就说该语句之后的输出内容将会继续被添加至缓冲区。
    • ob_flush :释放内部缓冲区的内容,并删除内部缓冲区的内容,但不关闭缓冲区。
    • flush: 将ob_flush释放出来的内容,以及不在PHP缓冲区中的内容,全部输出至浏览器。
    • ob_end_clean :删除内部缓冲区的内容,并关闭缓冲区。
    • ob_end_flush :释放内部缓冲区的内容,并关闭缓冲区。
  • 其它
    • ob_gzhandler: ob_start 回调函数,用gzip压缩缓冲区的内容。
    • ob_implicit_flush: 打开或关闭绝对刷新,默认为关闭(但受implicit_flush选项的制约)。所谓绝对刷新,即当有输出语句(e.g. echo)被执行时,便把输出直接发送到浏览器,而不再需要调用 flush()或等到脚本结束时才输出。
    • ob_list_handlers :List all output handlers in use
    • output_add_rewrite_var: Add URL rewriter values
    • output_reset_rewrite_vars — Reset URL rewriter values
还是无法顺序输出,再google得 php内部缓存一文,
一些Web服务器的output_buffering默认是4069字符或者更大,即输出内容必须达到4096字符服务器才会flush刷新输出缓冲,为 了确保flush有效,最好在ob_flush()函数前有以下语句:
print str_repeat(" ", 4096); //以确保到达output_buffering值。
再测试,ok,看来来我测试用pipni服务器也是这问题,虽然phpinfo得到
output_buffering no value no value
但试验得出似乎是这个的问题。于是代码如下:

for($i=0;$i<20;$i++) {
    echo $i.'
'; echo str_pad('', 4096); if(ob_get_length()){ ob_start(); ob_flush(); flush(); ob_end_flush(); } sleep(1); }
顺利地顺序输出了:
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
这样php服务端的长连接就可以准备好了~

转载于:https://www.cnblogs.com/defims/archive/2010/11/24/2946683.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值