再说php输出缓冲控制那些事

本文主要探讨了PHP的输出缓冲控制,包括output_buffering的开启情况对程序的影响,以及ob_start(), ob_flush(), ob_end_flush()等函数的作用。通过实例分析了在不同设置下,数据如何在PHP缓冲和服务器缓冲之间流动,以及如何正确调整代码以实现期望的输出效果。" 104155965,9224010,MySQL预处理详解与优势,"['MySQL', '数据库', '数据库优化']
摘要由CSDN通过智能技术生成

之前转了一篇关于php输出缓冲控制的文章:http://blog.csdn.net/adslcom/article/details/8282342 用来方便之后查看的。对于内容的例子代码也没有一一测试,今天调试了一下,发现自己对php输出缓冲的理解还是不够,导致在调试过程中发现很多不解的情况。经过一番google和测试,总算明白了一些。这里记录一下,也方便大家看看我的理解是否有误。

针对上篇文章的例子3和4:

<?php
/*例3*/
echo str_pad('', 1024);//使浏览器缓冲区溢出
ob_start();//打开缓冲区
echo 'oschina.net';
ob_flush();//送出当前缓冲内容,不会输出
flush();//输出送出的缓冲内容
sleep(1);
echo '红薯';
ob_flush();//送出当前缓冲内容,不会输出
flush();//输出送出的缓冲内容
sleep(1);
echo '虫虫';
ob_end_flush();//输出并关闭缓冲
?>

例子4:

<?php
/*例4*/
echo str_pad('', 1024);//使浏览器缓冲区溢出
echo 'oschina.net';
flush();//输出送出的缓冲内容
sleep(1);
echo '红薯';
flush();//输出送出的缓冲内容
sleep(1);
echo '虫虫';
?>

要达到实时显示,每隔1秒显示一个。前提是php.ini的output_buffering是关闭的,即output_buffering=Off(为了灵活调用flush(),implicit_flush = Off一直是关闭的)。

好的,现在来说说为什么?

先说说php输出顺序吧。如图:


php输出缓冲是支持嵌套的,可堆叠的。如果output_buffering=On,默认就开启了一个buffer。这个buffer肯定是最外层的。调用ob_start()就是手动开启一个buffer。

例子3,如果output_buffering=On,那就默认开启了一个buffer,先命名为buffer1,然后程序调用ob_start(),手动开启另一个buffer,命名为buffer2。调用ob_flush把buffer2的内容输出到上一层buffer1去,然后调用flush,flush是针对

server buffering的,刷新server buffering的缓冲,输出到浏览器去显示。现在的问题是数据还在buffer1即php output_buffering这个阶段,而server buffering还没有数据。所以数据没有实时显示出来。

例子4,正是output_buffer=Off,所以echo的内容直接到server buffering去了,然后调用flush,flush就会把server buffering的数据输出到浏览器去。如果output_buffering开启了,那数据就到php的output_buffering那,flush就没有效果了。

那如果output_buffering=On,上面的代码怎么修改了?

最简单是先关闭默认开启的buffer就可以了:

<?php
/*修改的例3*/
echo ob_get_level();// 1,默认开启了一个buffer
ob_end_clean();//清空,删除默认开启的buffer
echo ob_get_level();// 0,删除了
echo str_pad('', 1024);//使浏览器缓冲区溢出
ob_start();//打开缓冲区
echo 'oschina.net';
ob_flush();//送出当前缓冲内容,不会输出
flush();//输出送出的缓冲内容
sleep(1);
echo '红薯';
ob_flush();//送出当前缓冲内容,不会输出
flush();//输出送出的缓冲内容
sleep(1);
echo '虫虫';
ob_end_flush();//输出并关闭缓冲
?>

复杂的点:

<?php
/*修改的例3*/
echo str_pad('', 1024);//使浏览器缓冲区溢出
ob_start();//打开缓冲区buffer2
echo 'oschina.net';
ob_end_flush();//把buffer2的内容输出到buffer1,关掉buffer2
ob_flush();//把buffer1的内容输出到server buffer
flush();//输出送出的缓冲内容

sleep(1);

ob_start();//buffer2
echo '红薯';
ob_end_flush;//同上
ob_flush();//同上
flush();//输出送出的缓冲内容

sleep(1);

ob_start();//buffer2
echo '虫虫';
ob_end_flush();//同上
ob_flush();//同上
flush();
?>
分析得出:

ob_end_flush、ob_flush针对的是php buffering,flush针对的是server buffering。只有php buffering到了最外层,再调用ob_flush or ob_end_flush才是把数据从php buffering出到server buffering。如果不是最外层,那只是送出到外层的

php buffering去而已。然后还有一个问题就是浏览器缓冲,在执行之前,都会先输出1024个字节数,就是为了浏览器的缓冲溢出。问题是为什么这个输出不会给php buffering起来,可以直接输出?还是说哪块理解错误了?大家知道的就麻烦告诉小弟啦,上面的分析有错的也请指出来,谢谢啦!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值