基于PHP输出缓存(output_buffering)的深入理解


Posted in PHP onJune 13, 2013

首先明确一下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)

<html>
     <body>
         <?php
             // ob_start();    //这玩意开了就会不正常,输出不受ob_flush()控制,不知道到底干嘛用
             // echo str_repeat(' ' ,1000);    //IE缓存256Bytes
             echo str_repeat(' ' ,1000);    //Chrome和FF缓存1000Bytes,这里用来先将浏览器缓存用掉,但是很疑惑这一行输出为什么没有被output_buffering存起来,而是直接输出了
             for($i=0;$i<5;$i++) {
                 echo $i.'<br />';
                 ob_flush();
                 flush();
                 sleep(1);
             }
         ?>
     </body>
 </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.
4.甚至浏览器也会在显示之前,缓存接收到的内容。例如 Netscape
5.浏览器会在接受到换行或 html 标记的开头之前缓存内容,并且在
6.接受到 </table> 标记之前,不会显示出整个表格。
7.
8.一些版本的 Microsoft Internet Explorer 只有当接受到的256个
9.字节以后才开始显示该页面,所以必须发送一些额外的空格来让这
10.些浏览器显示页面内容。
所以, 正确使用俩者的顺序是. 先ob_flush, 然后flush,
当然, 在其他sapi下, 不调用flush也可以, 只不过为了保证你代码的可移植性, 建议配套使用.

PHP 相关文章推荐
php中利用post传递字符串重定向的实现代码
Apr 21 PHP
ThinkPHP之N方法实例详解
Jun 20 PHP
PHP采用get获取url汉字出现乱码的解决方法
Nov 13 PHP
php采用session实现防止页面重复刷新
Dec 24 PHP
php自动加载方式集合
Apr 04 PHP
PHP实现对数组分页处理实例详解
Feb 07 PHP
PHP基于Redis消息队列实现发布微博的方法
May 03 PHP
phpStudy配置多站点多域名方法及遇到的403错误解决方法
Oct 19 PHP
yii2安装详细流程
May 23 PHP
php防止表单重复提交实例讲解
Feb 11 PHP
php加速缓存器opcache,apc,xcache,eAccelerator原理与配置方法实例分析
Mar 02 PHP
PHP中关于php.ini参数优化详解
Feb 28 PHP
php缓冲 output_buffering的使用详解
Jun 13 #PHP
如何在PHP中使用正则表达式进行查找替换
Jun 13 #PHP
php启用zlib压缩文件的配置方法
Jun 12 #PHP
Window下PHP三种运行方式图文详解
Jun 11 #PHP
控制PHP的输出:缓存并压缩动态页面
Jun 11 #PHP
基于PHP导出Excel的小经验 完美解决乱码问题
Jun 10 #PHP
win7+apache+php+mysql环境配置操作详解
Jun 10 #PHP
You might like
德生PL450的电路分析和低放电路的改进办法
2021/03/02 无线电
PHP中集成PayPal标准支付的实现方法分享
2012/02/06 PHP
用php实现百度网盘图片直链的代码分享
2012/11/01 PHP
使用PHPExcel操作Excel用法实例分析
2015/03/26 PHP
WordPress中用于创建以及获取侧边栏的PHP函数讲解
2015/12/29 PHP
ThinkPHP框架整合微信支付之Native 扫码支付模式一图文详解
2019/04/09 PHP
laravel框架语言包拓展实现方法分析
2019/11/22 PHP
基于jQuery的合并表格中相同文本的相邻单元格的代码
2011/04/06 Javascript
js中的caller和callee属性介绍和例子
2014/06/07 Javascript
jQuery+ajax实现鼠标单击修改内容的方法
2014/06/27 Javascript
利用js获取下拉框中所选的值
2016/12/01 Javascript
javascript设计模式之Adapter模式【适配器模式】实现方法示例
2017/01/13 Javascript
JavaScript之DOM插入更新删除_动力节点Java学院整理
2017/07/03 Javascript
AngularJS动态添加数据并删除的实例
2018/02/27 Javascript
vue 组件中添加样式不生效的解决方法
2018/07/06 Javascript
详解如何用webpack4从零开始构建react开发环境
2019/01/27 Javascript
vue 实现通过vuex 存储值 在不同界面使用
2019/11/11 Javascript
在vue中使用cookie记住用户上次选择的实例(本次例子中为下拉框)
2020/09/11 Javascript
[49:05]Newbee vs TNC 2018国际邀请赛小组赛BO2 第一场 8.16
2018/08/17 DOTA
在Python程序中操作MySQL的基本方法
2015/07/29 Python
python字符串,数值计算
2016/10/05 Python
详解python上传文件和字符到PHP服务器
2017/11/24 Python
scrapy spider的几种爬取方式实例代码
2018/01/25 Python
Python实现的txt文件去重功能示例
2018/07/07 Python
numpy的文件存储.npy .npz 文件详解
2018/07/09 Python
python能开发游戏吗
2020/06/11 Python
python集合能干吗
2020/07/19 Python
图解Python中深浅copy(通俗易懂)
2020/09/03 Python
pycharm中如何自定义设置通过“ctrl+滚轮”进行放大和缩小实现方法
2020/09/16 Python
python性能测试工具locust的使用
2020/12/28 Python
亚瑟士美国官网:ASICS美国
2017/02/01 全球购物
ANINE BING官方网站:奢华的衣橱基本款和时尚永恒的单品
2019/11/26 全球购物
代理人委托书
2014/09/16 职场文书
教师年度考核自我评鉴
2015/08/11 职场文书
python实现股票历史数据可视化分析案例
2021/06/10 Python
Nginx安装配置详解
2022/06/25 Servers