php ob_statrt 缓冲系列函数分析
来源:互联网 发布:国培计划2015网络研修 编辑:程序博客网 时间:2024/06/16 07:48
ob_start() 和 ob_end_flush() 是一对很好的搭档,可以实现对输出的控制。当成一对出现理解起来就没什么问题,但是当他们两个各自出现次数增加时,就比较难理解了.
01
<?php
02
ob_start();
03
echo
'level 1<br/> '
;
04
ob_start();
05
echo
'level 2<br/> '
;
06
ob_start();
07
echo
'level 3<br/> '
;
08
ob_end_flush();
09
ob_end_flush();
10
ob_end_flush();
level 1
level 2
level 3
当程序修改一下,修改一个ob_end_flush() 变成 ob_end_clean() 成为以下这个,你觉得结果会是怎样呢?附上这几个函数的讲解:
- ob_clean — 清空(擦掉)输出缓冲区,不会销毁缓冲区
- ob_end_clean — 清空(擦除)缓冲区并关闭输出缓冲
- ob_end_flush — 冲刷出(送出)输出缓冲区内容并关闭缓冲
- ob_flush — 冲刷出(送出)输出缓冲区中的内容,但不会销毁缓冲区。这是与ob_end_flush区别的地方
- ob_start — 打开输出控制缓冲
01
<?php
02
ob_start();
03
echo
'level 1<br/> '
;
04
ob_start();
05
echo
'level 2<br/> '
;
06
ob_start();
07
echo
'level 3<br/> '
;
08
ob_end_clean();
//修改处
09
ob_end_flush();
10
ob_end_flush();
level 1
level 2
可能你会认为ob_end_clean()会清除与他最近的ob_start()的输出;其实这个说法不是很全面,看下面的例子
01
<?php
02
ob_start();
03
echo
'level 1<br/> '
;
04
ob_start();
05
echo
'level 2<br/> '
;
06
ob_start();
07
echo
'level 3<br/> '
;
08
ob_end_clean();
//第一次修改
09
ob_end_flush();
10
ob_end_clean();
//第二次修改
中间不是有一个ob_flush()吗?按理来说应该是输出 level2 的。
其实造成这样的主要原因是输出的多级缓冲机制。这个程序例子有三个ob_start(),就意味着他有3个缓冲区A,B,C,而其实PHP程序本身也有一个最终输出的缓冲区,我们就把他叫做F。
在这个程序中他这几个缓冲区是有一定层次的,C->B->A->F,F层次最高,是程序最终的输出缓冲,我们按上面的程序来进行讲解。
刚开始。 F:null
1
ob_start();
新建缓冲区A。 A: null -> F:null
1
echo
'level 1<br/> '
;
程序有输出,输出进入最低的缓冲区A A: 'level 1<br/>' -> F:null
1
ob_start();
新建缓冲区B 。 B:null -> A: 'level 1<br/>' -> F:null
1
echo
'level 2<br/> '
;
程序有输出,输出进入最低的缓冲区B B:'level 2<br/> ' -> A: 'level 1<br/>' ->F:null
1
ob_start();
新建缓冲区C C:null B:'level 2<br/> ' A: 'level 1<br/>' -> F:null
1
echo
'level 3<br/> '
;
程序有输出,输出进入最低的缓冲区C C:'level 3<br/> ' -> B:'level 2<br/> ' -> A: 'level 1<br/>' -> F:null
1
ob_end_clean();
//第一次修改
缓冲区C被清空并关闭。 B:'level 2<br/> ' -> A: 'level 1<br/>' -> F:null
1
ob_end_flush();
缓冲区B输出到上一级的缓冲区A并关闭。 A: 'level 1<br/>level 2<br/> ' -> F:null
1
ob_end_clean();
//第二次修改
缓冲区A被清空并关闭。 此时缓冲区A的东西还没真正输出到最终的F中,因此也就整个程序也就没有任何的输出了。
ob其他的函数还有很多,但只要能懂得这些机理应该也是不难懂的。附上其余函数
- flush — 刷新输出缓冲
- ob_clean — 清空(擦掉)输出缓冲区
- ob_end_clean — 清空(擦除)缓冲区并关闭输出缓冲
- ob_end_flush — 冲刷出(送出)输出缓冲区内容并关闭缓冲
- ob_flush — 冲刷出(送出)输出缓冲区中的内容
- ob_get_clean — 得到当前缓冲区的内容并删除当前输出缓。
- ob_get_contents — 返回输出缓冲区的内容
- ob_get_flush — 刷出(送出)缓冲区内容,以字符串形式返回内容,并关闭输出缓冲区。
- ob_get_length — 返回输出缓冲区内容的长度
- ob_get_level — 返回输出缓冲机制的嵌套级别
- ob_get_status — 得到所有输出缓冲区的状态
- ob_gzhandler — 在ob_start中使用的用来压缩输出缓冲区中内容的回调函数。ob_start callback function to gzip output buffer
- ob_implicit_flush — 打开/关闭绝对刷送
- ob_list_handlers — 列出所有使用中的输出处理程序。
- ob_start — 打开输出控制缓冲
- output_add_rewrite_var — 添加URL重写器的值(Add URL rewriter values)
- output_reset_rewrite_vars — 重设URL重写器的值(Reset URL rewriter values)
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也可以, 只不过为了保证你代码的可移植性, 建议配套使用.
Note that you still need a minimum amount of data to come through the browser filter. I would advice using str_pad($text,4096); since this automatically lenghtens the text with spaces to 4 KB which is the minimum limit when using FireFox and linux.
- php ob_statrt 缓冲系列函数分析
- 关于PHP开启缓冲函数系列函数
- php缓冲函数
- PHP输出缓冲(三)-- 相关缓冲函数
- php中有关缓冲内置函数
- PHP源代码分析-字符串搜索系列函数实现详解
- php缓冲--ob缓冲
- PHP array系列函数
- readv函数与sendv函数即相关缓冲分析
- termios 系列函数分析
- 缓冲I/O与非缓冲I/O(fopen与open系列函数区别)
- 缓冲I/O与非缓冲I/O(fopen与open系列函数区别)
- 缓冲I/O与非缓冲I/O(fopen与open系列函数区别)
- php缓冲---ob缓冲深入
- PHP输出缓冲控制 - Output Control 函数 应用详解
- PHP输出缓冲控制 - Output Control 函数 应用详解
- IO缓冲,php中的ob缓冲机制,以及socket、curl、fopen这些函数的底层关系
- 【php】PHP缓冲剖析
- 第十一周:C语言:判断闰年
- Zabbix 3.0 监控MySQL [六]
- 携程React Native实践
- 初学 Java Web 开发,请远离各种框架,从 Servlet 开发
- Zabbix 3.0 监控Web [七]
- php ob_statrt 缓冲系列函数分析
- com.genuitec.runtime.generic.jee60 is not defined的解决方法
- python环境管理
- loadrunner web脚本发送文件
- 第十一周 OJ 循环画三角形
- C#超基础:静态数组与动态数组的区别
- Mysql缓存命中率
- Java-JFrame
- hihocoder1136-DAG和DP的关系