ob_start() 和 ob_end_flush() 是一对很好的搭档,可以实现对输出的控制。当成一对出现理解起来就没什么问题,但是当他们两个各自出现次数增加时,就比较难理解了.

<?php
ob_start();
echo 'level 1<br/> ';
ob_start();
echo 'level 2<br/> ';
ob_start();
echo 'level 3<br/> ';
ob_end_flush();
ob_end_flush();
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_start — 打开输出控制缓冲
<?php
ob_start();
echo 'level 1<br/> ';
ob_start();
echo 'level 2<br/> ';
ob_start();
echo 'level 3<br/> ';
ob_end_clean();//修改处
ob_end_flush();
ob_end_flush();

  

结果:

level 1
level 2

可能你会认为ob_end_clean()会清除与他最近的ob_start()的输出;其实这个说法不是很全面,看下面的例子

<?php
ob_start();
echo 'level 1<br/> ';
ob_start();
echo 'level 2<br/> ';
ob_start();
echo 'level 3<br/> ';
ob_end_clean(); //第一次修改
ob_end_flush();
ob_end_clean(); //第二次修改

  

这次,什么都没有输出来。

中间不是有一个ob_flush()吗?按理来说应该是输出  level2 的。

其实造成这样的主要原因是输出的多级缓冲机制。这个程序例子有三个ob_start(),就意味着他有3个缓冲区A,B,C,而其实php程序本身也有一个最终输出的缓冲区,我们就把他叫做F。

在这个程序中他这几个缓冲区是有一定层次的,C->B->A->F,F层次最高,是程序最终的输出缓冲,我们按上面的程序来进行讲解。

刚开始。  F:null

ob_start();

  

新建缓冲区A。  A: null -> F:null

echo   'level 1<br/> ';

  

程序有输出,输出进入最低的缓冲区A  A: 'level 1<br/>' -> F:null

ob_start();

  

新建缓冲区B 。 B:null  ->  A: 'level 1<br/>' -> F:null

echo   'level 2<br/> ';

  

程序有输出,输出进入最低的缓冲区B     B:'level 2<br/> ' ->  A: 'level 1<br/>' ->F:null

ob_start();

新建缓冲区C   C:null  B:'level 2<br/> '   A: 'level 1<br/>' -> F:null

echo   'level 3<br/> ';

  

程序有输出,输出进入最低的缓冲区C    C:'level 3<br/> '  ->  B:'level 2<br/> '  ->  A: 'level 1<br/>' -> F:null

ob_end_clean(); //第一次修改

缓冲区C被清空并关闭。  B:'level 2<br/> '  ->  A: 'level 1<br/>' -> F:null

ob_end_flush();

缓冲区B输出到上一级的缓冲区A并关闭。   A: 'level 1<br/>level 2<br/> ' -> F:null

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_start()、ob_end_flush和ob_end_clean()多级缓冲的更多相关文章

  1. php ob_start()、ob_end_flush和ob_end_clean()多级缓冲

    ob_start() 和 ob_end_flush() 是一对很好的搭档,可以实现对输出的控制.当成一对出现理解起来就没什么问题,但是当他们两个各自出现次数增加时,就比较难理解了. <?php ...

  2. 【转】php ob_start()、ob_end_flush和ob_end_clean()多级缓冲

    原文:https://my.oschina.net/CuZn/blog/68650 当php.ini配置文件中的  设置开启的时候,就相当于PHP已经打开了最顶层的 一级缓存 (等价于调用了一次 ob ...

  3. 【转】php缓冲 output_buffering和ob_start

    原文: http://blog.csdn.net/21aspnet/article/details/7389427 php缓冲 output_buffering和ob_start buffer buf ...

  4. PHP输出缓冲控制

    说到输出缓冲,首先要说的是一个叫做缓冲器(buffer)的东西.举个简单的例子说明他的作用:我们在编辑一篇文档时,在我们没有保存之前,系统是不会 向磁盘写入的,而是写到buffer中,当buffer写 ...

  5. PHP输出缓冲控制- Output Control 函数应用详解

    说到输出缓冲,首先要说的是一个叫做缓冲器(buffer)的东西.举个简单的例子说明他的作用:我们在编辑一篇文档时,在我们没有保存之前,系统是不会向磁盘写入的,而是写到buffer中,当buffer写满 ...

  6. [PHP]php缓冲 output_buffering的使用详解

    bufferbuffer是一个内存地址空间,Linux系统默认大小一般为4096(4kb),即一个内存页.主要用于存储速度不同步的设备或者优先级不同的设备之间传办理数据的区域.通过buffer,可以使 ...

  7. PHP输出缓冲控制 - Output Control 函 应用详解

    简介 说到输出缓冲,首先要说的是一个叫做缓冲器(buffer)的东西.举个简单的例子说明他的作用:我们在编辑一篇文档时,在我们没有保存之前,系统是不会向磁盘写入的,而是写到buffer中,当buffe ...

  8. 【转】PHP ob_start() 函数介绍

    php ob_start 与 ob_end_flush() 是 php 的缓冲输出函数. ob_start([string output_callback])- 打开输出缓冲区,所有的输出信息不在直接 ...

  9. PHP 输出缓冲控制(Output Control) 学习

    php 缓冲简介 其实我对php ob 系列印象还是很模糊,具体怎么玩的,还不是很了解,平时curd,确实对这些内容没有深入.作为phper 甚是惭愧.网上搜了一通,互相copy,代码运行不能出现作者 ...

随机推荐

  1. jQuery选择器详解及实例---《转载》

    选择器是jQuery最基础的东西,本文中列举的选择器基本上囊括了所有的jQuery选择器,也许各位通过这篇文章能够加深对jQuery选择器的理解,它们本身用法就非常简单,我更希望的是它能够提升个人编写 ...

  2. oracle一些笔记

    1.字符串类型字段 区分大小写 where table_name = 'MIDDLE' 2.execute immediate '' bulk collect into v_xxx_tab 3.列别名 ...

  3. MyBatis的动态插入语句(经常报‘无效的列类型’)

    最近在工作中经常遇到一个情况:通过mybatis的标签执行插入语句,当表中字段比较多的时候,需要全部插入,而有时候的需求是只插入其中几个字段,但是会报错. 原来的语句,必须把所有字段都Set值. &l ...

  4. PHP性能调优,PHP慢日志---PHP脚本执行效率性能检测之WebGrind的使用

    如何一睹webgrind这个神奇的php性能检测工具神奇呢? 废话不多说首先webgrind这个性能检测是需要xdebug来配合,因为webgrind 进行性能检测分析就是通过xdebug生成的日志文 ...

  5. 防止一个exe被打开多次

    mutex有一个名字,如果这个exe已经打开了,createNew返回的就是false,程序就退出了. 这是个wpf application的例子 protected override void On ...

  6. hdu 3951 硬币围成一圈(博弈)

    n个硬币围成一个环 每次只能取1-K个硬币 最后取完者胜 假如5个硬币 每次取1-2个情况1 先手取1个 后手取剩下4个中间2个 破坏了连续 虽然最后剩2个,但先手只能取一个 然后后再取一个 后手胜 ...

  7. hdu 5122 (2014北京现场赛 K题)

    把一个序列按从小到大排序 要执行多少次操作 只需要从右往左统计,并且不断更新最小值,若当前数为最小值,则将最小值更新为当前数,否则sum+1 Sample Input255 4 3 2 155 1 2 ...

  8. [水煮 ASP.NET Web API2 方法论](3-1)集中式路由

    问题 怎样集中的定义路由 解决方案 通过调用 HttpRouteCollectionExtension 类中的 MapHttpRoute 扩展方法在 HttpRouteCollection 中定义路由 ...

  9. 【Codechef】Random Number Generator(多项式除法)

    题解 前置技能 1.多项式求逆 求\(f(x)\*g(x) \equiv 1 \pmod {x^{t}}\) 我们在t == 1时,有\(f[0] = frac{1}{g[0]}\) 之后呢,我们倍增 ...

  10. 【AtCoder】ARC096(C - F)

    听说日本题思维都很棒,去涨涨智商qwq C - Half and Half 题解 枚举买多少个AB披萨也行 但是关于买x个AB披萨最后的总花费是个单峰函数,可以三分 这题有点像六省联考2017D1T1 ...