php中ob函数缓冲机制深入理解


Posted in PHP onAugust 03, 2015

下面就php中ob函数缓冲机制通过文字说明加代码分析的形式给大家展示如下:

对于一个刚刚入门的php程序员来说,php缓冲区是几乎透明的。在他们心目中,一个echo print_r 函数,数据便会‘嗖'的一声飞到浏览器上,显示出来。我也一直如此单纯地认为。 其实,在技术的世界里,向来都是由简单到复杂,也许那些技术开发者开始单纯如你我,但是面对残酷的现实,不得不调整策略,以期提高机器运行效率,最后想到了那些让我们赞叹的idea。

说到缓冲,也就是buffer,这里必须要和缓存做一下比较,单纯地比较定义是无意义的,莫不如看看它们做什么。缓存解决的是如何快速查找利用数据,节省cpu消耗问题,而缓冲解决的是高速cpu与低速I/O设备不匹配的问题。

再说下本文的另一个主角,ob函数,ob是output_buffering的简写。既然ob函数是php扩展函数,那么ob函数主要操作的也就是php buffer了。

简单说完本文两个主角,我们还必须回归开头的主题,echo print_r函数输出的数据是怎么到达浏览器让用户看到的呢?实际上的历程是这样的:

echo、print_r=>php output_buffering=>webServer buffer=>browser buffer=>browser display

我们可以清楚地看到,从echo、print_r函数到发送信息给客户端经历了两个缓冲区,在客户端还经历了一个浏览器缓冲区。我们本文主要讨论的是php output_buffering

未使用ob函数时缓冲区的使用情况

 

我们的代码很多时候是根本不使用ob函数的,那么它们使用缓冲区了吗?这要看php设置情况。缓冲区是通过php.ini中的output_buffering变量控制的。其默认值是off,可以设置为on来打开buffer。打来buffer后,即便程序中没有用ob函数,实际上代码也是使用了缓冲区的。另外,不管php.ini中output_buffering的设置,cli模式下的php始终默认是关闭的。

为什么要是缓冲区呢?简单来说,高速的cpu早早处理完自己的数据,想通过线路传递给用户,但是线路太窄了,一下输送不过去。如果引入缓冲区,cpu可以将快速将生成的数据放入缓冲区,然后自己哪儿凉快儿哪儿呆着这歇着去了。缓冲区根据指令适时将数据输出。这个样就合理解决了高速cpu与低速I/O设备的矛盾了。 

缓冲区的数据什么时候输出呢?1,当缓冲区满了的时候,缓冲是有容量大小的,到达极限则会自动输出内容。2,脚本执行完毕。很多小程序输出内容没那么多,总不能等到缓冲区满了再输出吧~这一点再自然不过。

使用ob函数时缓冲区的使用情况

 ob_start()

打开输出缓冲。这个函数是我们调用最多的一个函数之一。在output_buffering设置为on或者x k的情况下,这个函数与其说是打开输出缓冲,还不如说将输出缓冲扩充到很大。当然在output_buffering设置为off的条件下,ob_start会起到打开buffer的作用。ob_start()还可以传递一个可选参数 output_callback 函数,php官方手册有详细说明。

ob_get_contents()

只是得到输出缓冲区的内容,但不清除它。

ob_end_clean()与ob_clean()

这两个函数从字面意思上就可以看出其区别。前者清除缓冲区内容并且关闭,后者仅仅是做清除工作。需要注意的是,使用了这两个函数,在前面使用了echo、print_r等函数不会输出内容。

笔者曾经试图通过print_r打印出ob_get_contents()的内容,然后调用ob_clean()清除缓冲区,以免影响后面对缓冲区的操作,屡屡失败。仔细想想,print_r的内容再次写入缓冲区,而后面做了ob_clean()的操作,自然不会有任何输出。在ob_clean操作之前调用ob_flush()函数便可达到预想的效果。

ob_flush()与flush()

ob_flush()送出缓冲区的内容并且丢弃内容。因而在此函数之前最好采用ob_get_contents()获得缓冲区内容。flush()刷出服务器端缓冲,并且发往客户端。因而从流程上来说,应该是先调用ob_flush()而后再调用flush函数。

另外说明下再Apache buffer flush()的工作原理:在apache module的sapi下,flush会通过调用sapi_module()的flush成员函数指针,间接使用apache的api::ap_rflush刷新apache的输出缓冲区。当然apache其他模块比如mod_gzip可能改变这个动作的结果,可能自己进行输出缓冲区,这将导致flush()函数产生的结果不会立即被送到客户端浏览器。

ob_get_clean()

如果你已经熟练掌握ob_get_contents()ob_clean(),那这个函数就很简单了。因为它是前两者的结合体。它主要是得到当前缓冲区的内容并删除当前输出缓冲区。

ob函数还有很多,但大部分用法比较简单,理解较为容易。大家可以参照php手册 ,里面会有详细的解释。本文列出了笔者开始并不是很理解的一些函数,当然今后还会有新的问题出现,想到问题并且解决问题,生活的乐趣也许就在此处吧。

以上内容就是本文针对php中ob函数缓冲机制深入理解,希望对大家今后学习有所帮助。

PHP 相关文章推荐
php不用正则采集速度探究总结
Mar 24 PHP
php读取msn上的用户信息类
Dec 05 PHP
php Try Catch异常测试
Mar 01 PHP
php foreach 使用&(与运算符)引用赋值要注意的问题
Feb 16 PHP
如何使用“PHP” 彩蛋进行敏感信息获取
Aug 07 PHP
一个简单的PHP验证码实现代码
May 10 PHP
Linux下PHP连接Oracle数据库
Aug 20 PHP
浅谈PHP正则表达式中修饰符/i, /is, /s, /isU
Oct 21 PHP
php通过分类列表产生分类树数组的方法
Apr 20 PHP
php 判断过去离现在几年的函数(实例代码)
Nov 15 PHP
thinkPHP订单数字提醒功能的实现方法
Dec 01 PHP
laravel框架之数据库查出来的对象实现转化为数组
Oct 23 PHP
如何利用http协议发布博客园博文评论
Aug 03 #PHP
在CentOS上搭建LAMP+vsftpd环境的简单指南
Aug 01 #PHP
如何使用php实现评委评分器
Jul 31 #PHP
php给图片加文字水印
Jul 31 #PHP
初识通用数据库操作类――前端easyui-datagrid,form(php)
Jul 31 #PHP
使用Appcan客户端自动更新PHP版本号(全)
Jul 31 #PHP
php使用Imagick生成图片的方法
Jul 31 #PHP
You might like
php桌面中心(四) 数据显示
2007/03/11 PHP
PHP中获取文件创建日期、修改日期、访问时间的方法
2016/11/05 PHP
体验js中splice()的强大(插入、删除或替换数组的元素)
2013/01/16 Javascript
基于JavaScript判断浏览器到底是关闭还是刷新(超准确)
2016/02/01 Javascript
jQuery+ajax实现滚动到页面底部自动加载图文列表效果(类似图片懒加载)
2016/06/07 Javascript
Nodejs全局安装和本地安装的不同之处
2016/07/04 NodeJs
js自调用匿名函数的三种写法(推荐)
2016/08/19 Javascript
Bootstrapvalidator校验、校验清除重置的实现代码(推荐)
2016/09/28 Javascript
关于angularJs指令的Scope(作用域)介绍
2016/10/25 Javascript
不使用JavaScript实现菜单的打开和关闭效果demo
2018/05/01 Javascript
分享5个好用的javascript文件上传插件
2018/09/16 Javascript
js实现按钮开关单机下拉菜单效果
2018/11/22 Javascript
vue canvas绘制矩形并解决由clearRec带来的闪屏问题
2019/09/02 Javascript
javascript+css实现进度条效果
2020/03/25 Javascript
Python爬虫实例爬取网站搞笑段子
2017/11/08 Python
Python Django框架单元测试之文件上传测试示例
2019/05/17 Python
使用TensorFlow实现简单线性回归模型
2019/07/19 Python
python 列表、字典和集合的添加和删除操作
2019/12/16 Python
Python tkinter和exe打包的方法
2020/02/05 Python
Python HTMLTestRunner库安装过程解析
2020/05/25 Python
python适合做数据挖掘吗
2020/06/16 Python
Python colormap库的安装和使用详情
2020/10/06 Python
Python实现疫情地图可视化
2021/02/05 Python
HTML5使用Audio标签实现歌词同步的效果
2016/03/17 HTML / CSS
html5移动端自适应布局的实现
2020/04/15 HTML / CSS
英国经典球衣网站:Classic Football Shirts
2017/05/20 全球购物
Pottery Barn阿联酋:购买家具、家居装饰及更多
2019/12/08 全球购物
机械设计及其自动化专业推荐信
2013/10/31 职场文书
生产班组长岗位职责
2014/01/05 职场文书
《翻越远方的大山》教学反思
2014/04/13 职场文书
贵阳市党的群众路线教育实践活动党(工)委领导班子整改方案
2014/10/26 职场文书
2015年清明节演讲稿范文
2015/03/17 职场文书
初中政治教学工作总结
2015/08/13 职场文书
小学生反邪教心得体会
2016/01/15 职场文书
申论不会写怎么办?教您掌握这6点思维和原则
2019/07/17 职场文书
Mysql中的触发器定义及语法介绍
2022/06/25 MySQL