设为首页 收藏本站
查看: 516|回复: 0

[经验分享] PHP输出缓存(output_buffering)小记

[复制链接]

尚未签到

发表于 2015-8-29 13:51:31 | 显示全部楼层 |阅读模式
  首先明确一下PHP的输出顺序
  1.打开了php输出缓存: echo,print -> php output_buffring -> server buffering -> browser buffering -> browser display
  2.未打开php输出缓存: echo,print -> server buffering -> browser buffering -> browser display
  
  另外明确一下浏览器的输出缓存:IE为256Bytes, Chrome与FireFox为1000Bytes,只有输出数据达到了这个长度或者脚本结束浏览器才会将数据输出在页面上
  
  再来说说用到的几个PHP设置和API:
  1.php.ini中的output_buffering配置


  • Off: 表示关闭PHP输出缓存
  • On: 打开无限大的输出缓存
  • 4096: 打开大小为4096Byte的输出缓存
  2.php.ini中的implicit_flush配置


  • On: 表示每次输出(如echo,print)后自动调用flush()函数后,直接输出
  • Off: 与On相反,每次输出后不会调用flush(),需要等到server buffering满了才会输出,但是我们可以用flush()函数代替它,不开启也没关系,反而更加灵活
  3.ob_flush()函数: 取出PHP buffering中的数据,放入server buffering
  4.flush()函数: 取出Server buffering的数据,放入browser buffering
  5.ob_start()函数:对于这个函数我现在了解的不是很清楚,因为开启后输出就会不受ob_flush()控制,即使使用ob_flush()和flush(),数据也不能立即输出在浏览器上.现在知道的是,如果output_buffering=Off,即使使用了ob_start(),也是无法将输出数据缓存的,而如果output_buffering=On的话,即使不用ob_start(),输出数据也可以被PHP缓存,所以觉得ob_start比较废,暂时不管他
  
  然后我们来看代码吧(设置output_buffering=4096,implicit_flush=Off)



1 <html>
2     <body>
3         <?php
4             // ob_start();    //这玩意开了就会不正常,输出不受ob_flush()控制,不知道到底干嘛用
5             // echo str_repeat(' ' ,1000);    //IE缓存256Bytes
6             echo str_repeat(' ' ,1000);    //Chrome和FF缓存1000Bytes,这里用来先将浏览器缓存用掉,但是很疑惑这一行输出为什么没有被output_buffering存起来,而是直接输出了
7             for($i=0;$i<5;$i++) {
8                 echo $i.'<br />';
9                 ob_flush();
10                 flush();
11                 sleep(1);
12             }
13         ?>
14     </body>
15 </html>
  这里代码输出结果是一行一行输出的,具体原理大家参考一下ob_flush()和flush()函数的功效
  这两个函数缺了任何一个在我这种设置下都是要等到 0, 1, 2, 3, 4都缓存起来后最后一起输出
  最后引用一段Laruence的一段blog,希望对大家的理解有帮助

  ob_flush/flush在手册中的描述, 都是刷新输出缓冲区, 并且还需要配套使用, 所以会导致很多人迷惑…
  其实, 他们俩的操作对象不同, 有些情况下, flush根本不做什么事情..
  ob_*系列函数, 是操作PHP本身的输出缓冲区.
  所以, ob_flush是刷新PHP自身的缓冲区.
  而flush, 严格来讲, 这个只有在PHP做为apache的Module(handler或者filter)安装的时候, 才有实际作用. 它是刷新WebServer(可以认为特指apache)的缓冲区.
  在apache module的sapi下, flush会通过调用sapi_module的flush成员函数指针, 间接的调用apache的api: ap_rflush刷新apache的输出缓冲区, 当然手册中也说了, 有一些apache的其他模块, 可能会改变这个动作的结果..


  • 有些Apache的模块,比如mod_gzip,可能自己进行输出缓存,
  • 这将导致flush()函数产生的结果不会立即被发送到客户端浏览器。

  • 甚至浏览器也会在显示之前,缓存接收到的内容。例如 Netscape
  • 浏览器会在接受到换行或 html 标记的开头之前缓存内容,并且在
  • 接受到 </table> 标记之前,不会显示出整个表格。

  • 一些版本的 Microsoft Internet Explorer 只有当接受到的256个
  • 字节以后才开始显示该页面,所以必须发送一些额外的空格来让这
  • 些浏览器显示页面内容。
  所以, 正确使用俩者的顺序是. 先ob_flush, 然后flush,
  当然, 在其他sapi下, 不调用flush也可以, 只不过为了保证你代码的可移植性, 建议配套使用.


运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-106002-1-1.html 上篇帖子: PHP单元测试学习记录(1) 下篇帖子: 关于PHP的header("P3P: CP=CURa……")
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表