首先明确一下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的其他模块, 可能会改变这个动作的结果..

  1. 有些Apache的模块,比如mod_gzip,可能自己进行输出缓存,
  2. 这将导致flush()函数产生的结果不会立即被发送到客户端浏览器。
  3. 甚至浏览器也会在显示之前,缓存接收到的内容。例如 Netscape
  4. 浏览器会在接受到换行或 html 标记的开头之前缓存内容,并且在
  5. 接受到 </table> 标记之前,不会显示出整个表格。
  6. 一些版本的 Microsoft Internet Explorer 只有当接受到的256个
  7. 字节以后才开始显示该页面,所以必须发送一些额外的空格来让这
  8. 些浏览器显示页面内容。

所以, 正确使用俩者的顺序是. 先ob_flush, 然后flush,

当然, 在其他sapi下, 不调用flush也可以, 只不过为了保证你代码的可移植性, 建议配套使用.

PHP输出缓存(output_buffering)小记 -- 尚有疑问相关推荐

  1. php 返回的缓存数据,基于PHP输出缓存(output_buffering)的深入理解

    首先明确一下PHP的输出顺序1.打开了php输出缓存: echo,print -> php output_buffring -> server buffering -> browse ...

  2. PHP的OB缓存(输出缓存)

    使用PHP自带的缓存机制 原则:如果ob缓存打开,则echo的数据首先放在ob缓存.如果是header信息,直接放在程序缓存.当页面执行到最后,会把ob缓存的数据放到程序缓存,然后依次返回给浏览器. ...

  3. PHP输出缓存控制详解及flush、ob_flush的区别

    原文地址:http://dao.daimaku.com/post/201006/133.html <?php for($i=0;$i<10;$i++) { echo $i.'<br ...

  4. php的缓冲器,php输出缓存控制

    一.什么是缓冲区? 答:就是把输入或者输出的内容先放进内存,而不显示或者读取,作用:协调高速CPU和相对缓慢的IO设备(磁盘等)的运作. 二.什么是php 输出缓存控制(Output Control) ...

  5. 页面输出缓存[转载]

    页面输出缓存作为最简单的缓存形式,输出缓存只是在内存中保留为响应请求而发送的HTML的副本.其后再有请求时将提供缓存的输出,直到缓存到期,这样,性能有可能得到很大的提高.     可以用以下几种方式进 ...

  6. 【翻译】ASP.NET 4中的可扩展输出缓存

    翻译自:http://weblogs.asp.net/scottgu/archive/2010/01/27/extensible-output-caching-with-asp-net-4-vs-20 ...

  7. ASP.NET页面输出缓存知识

    最近因项目要求,需要研究ASP.NET缓存,可是查阅了书本,msdn,网上后有点失望,真是天下文章一大抄啊,大家讲来讲去都是那么几点,没有条理,没有重点,也没有心得,所以我决定自己来写一篇,当然,我是 ...

  8. Output输出缓存区大小只有1024KB,超过大小限制的就会被清除

    pycharm默认的Output输出缓存区大小只有1024KB,超过大小限制的就会被清除,可以设置个较大值来解决显示不全,选择 Preferences -> Editor -> Conso ...

  9. ASP.NET 缓存技术(一)——启用页面输出缓存

    作者寄语:MSDN 是最好的老师,互联网是最智慧的生命体,分享是最重要的成长途径,技术的进步在于学习.实践和创新! 本系列所讲述的技术和展示的代码适用于 .NET Framework 4.0 和 II ...

最新文章

  1. NYOJ 366 D的小L
  2. Swift开发:仿Clear手势操作(拖拽、划动、捏合)UITableView
  3. Log4j输出格式控制
  4. ECharts Tooltip
  5. Android开发五 Android应用程序架构
  6. 百练1724:ROADS
  7. 什么是ABAP的STATE_READ_ACCESS
  8. OnSen UI结合AngularJs打造”美团APP我的”页面 --Hybrid App
  9. 图像处理之积分图应用三(基于NCC快速相似度匹配算法)
  10. LeetCode: Maximum Subarray
  11. 随记 elasticsearch
  12. nginx linux 下载安装,Linux(CentOS)下载安装Nginx并配置
  13. With语句是什么?
  14. Shell 获取进程号
  15. 逻辑回归-逐步回归(stepwise regression)的一些思考
  16. LTE学习笔记二:扁平化的组网架构
  17. u盘复制到计算机的文档打不开怎么办,U盘文件复制到别的电脑打不开怎么办
  18. 关于IT公司技术委员会职责
  19. 2014年蓝桥杯预赛 C/C++本科B组 解题报告 史丰收速算
  20. 史上最美大型互联网机房综合布线图鉴

热门文章

  1. 如何查看、备份电脑隐藏的恢复分区
  2. 帕金森定律(Parkinson's Law)
  3. 访问cdrom中的数据 linux
  4. IOS学习之UIDatePicker控件使用
  5. 无任何网络提供程序接受指定的网络路径 or No network provider accepted the given network path 的解决方法...
  6. 使用ODBC连接SQL Anywhere 5.0(asp)
  7. WMI使用技巧集 C#
  8. QT 中的 Graphics View 系统
  9. MFC中动态获取/设置按钮的文字
  10. MFC线程创建运行关闭的问题