【转】php ob_start()、ob_end_flush和ob_end_clean()多级缓冲
原文: https://my.oschina.net/CuZn/blog/68650
当php.ini配置文件中的 设置开启的时候,就相当于PHP已经打开了最顶层的 一级缓存 (等价于调用了一次 ob_start())
有多级缓存的时候, 调用ob_end_flush() 函数会关闭最里层的 一个缓存区,并将内容发送到它相邻的上面一层的缓冲区, 这句话是精髓。
---------------------------------------------------------------------------------------------------------------------------
ob_start() 和 ob_end_flush() 是一对很好的搭档,可以实现对输出的控制。当成一对出现理解起来就没什么问题,但是当他们两个各自出现次数增加时,就比较难理解了.
1 2 3 4 5 6 7 8 9 10 | <?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 — 打开输出控制缓冲
1 2 3 4 5 6 7 8 9 10 | <?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()的输出;其实这个说法不是很全面,看下面的例子
1 2 3 4 5 6 7 8 9 10 | <?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
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中,因此也就整个程序也就没有任何的输出了。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 25岁的心里话
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
2016-09-13 angularJS 系列(三)- 自定义 Service