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

下面就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函数缓冲机制深入理解,希望对大家今后学习有所帮助。

(0)

相关推荐

  • PHP使用ob_start生成html页面的方法

    本文实例讲述了PHP使用ob_start生成html页面的方法.分享给大家供大家参考.具体方法分析如下: ob_start([string output_callback])- 打开输出缓冲区 所有的输出信息不在直接发送到浏览器,而是保存在输出缓冲区里面,可选得回调函数用于处理输出结果信息. ob_end_flush - 结束(发送)输出缓冲区的内容,关闭输出缓冲区 使用output control 函数可以让自由控制脚本中数据的输出,这在我们想在header之前输出时很有用. 复制代码 代码如

  • php使用ob_start()实现图片存入变量的方法

    本文实例讲述了php使用ob_start()实现图片存入变量的方法.分享给大家供大家参考.具体实现方法如下: 用php的GD库处理完图片后,只能将图片用imagejpeg()输出,或者写入一个文件.很多时候并不需要这么做.比如要将图片存入数据库就需要把图片写入变量保存,用 ob_start() 启用缓存 ob_get_contents()获取缓存就可以将图片写入变量 复制代码 代码如下: <?php $imgPath ="图片地址" ; //获得图片信息 $imgPath 可以为

  • 使用php判断网页是否gzip压缩

    昨天晚上群里有朋友采集网页时发现file_get_contents 获得的网页保存到本地为乱码,响应的header 里 Content-Encoding:gzip但在浏览器里看是正常的.因为我有过相关经验马上发现是网站开启了gzip而file_get_contents 获得的是压缩过的页面,而不是解压过的页面(不知道是不是要file_get_conttents 请求网页时带上相应的参数,直接获得没有被gzip压缩过的网页?)刚好我前不久刚看到可以用读取文件的前2个字节判断文件类型.群里面的朋友也

  • 用php的ob_start来生成静态页面的方法分析

    虽然方法很多,但使用起来简便容易的,我觉得还是先判断已经生成的首页文件的生成时间和现有时间之间的差值,如果满足某个值就开始生成,这种方法比较来得容易,不多说了,开始吧! 在开始之前还是提一下三个函数吧:"ob_start().ob_end_clean().ob_get_contents()" ob_start():是打开缓冲区的,就是要把您需要生成的静态文件的内容缓存在这里: ob_get_contents():是读出缓冲区里的内容,下面有代码为例: ob_end_clean():这个

  • PHP压缩html网页代码(清除空格,换行符,制表符,注释标记)

    PHP压缩html网页代码 (清除空格,换行符,制表符,注释标记). 有个不错的方法就是压缩HTML,压缩html 其实就是:清除换行符,清除制表符,去掉注释标记 .它所起到的作用不可小视. 现提供PHP 压缩HTML函数.请大家不妨试试看,感觉还不错吧. 不废话了,直接上代码: 复制代码 代码如下: <?php /** * 压缩html : 清除换行符,清除制表符,去掉注释标记 * @param $string * @return 压缩后的$string * */ function compr

  • php读取远程gzip压缩网页的方法

    今天在调取一家商城的页面信息时候,使用file_get_contents抑或curl: 复制代码 代码如下: $url = 'http://www.xxx.com/21/?type=23′;  $temp = file_get_contents($url);  echo $temp; 都得到一片乱码,查看了许多内容,包括页面的header信息,发现原来页面使用了. 类似的信息,即Content-Encoding为gzip,即该站点开启了gzip压缩.这里的解决方案有多种,当然如果你使用file_

  • php ob_flush,flush在ie中缓冲无效的解决方法

    PHP程序的缓冲,而不论PHP执行在何种情况下(CGI ,web服务器等等).该函数将当前为止程序的所有输出发送到用户的浏览器. flush() 函数不会对服务器或客户端浏览器的缓存模式产生影响.因此,必须同时使用 ob_flush() 和flush() 函数来刷新输出缓冲. 个别web服务器程序,特别是Win32下的web服务器程序,在发送结果到浏览器之前,仍然会缓存脚本的输出,直到程序结束为止 自己写了个小例子,想在页面每隔一秒输出一个数字. 按照网上的代码: 复制代码 代码如下: ob_e

  • php缓冲 output_buffering和ob_start使用介绍

    buffer buffer是一个内存地址空间,Linux系统默认大小一般为4096(4kb),即一个内存页.主要用于存储速度不同步的设备或者优先级不同的设备之间传办理数据的区域.通过buffer,可以使进程这间的相互等待变少.这里说一个通俗一点的例子,你打开文本编辑器编辑一个文件的时候,你每输入一个字符,操作系统并不会立即把这个字符直接写入到磁盘,而是先写入到buffer,当写满了一个buffer的时候,才会把buffer中的数据写入磁盘,当然当调用内核函数flush()的时候,强制要求把buf

  • php中ob_get_length缓冲与获取缓冲长度实例

    本文实例讲述了php中ob_get_length缓冲与获取缓冲长度的方法.分享给大家供大家参考.具体方法如下: file_get_contents() 函数把整个文件读入一个字符串中,和 file() 一样,不同的是 file_get_contents() 把文件读入一个字符串. file_get_contents() 函数是用于将文件的内容读入到一个字符串中的首选方法,如果操作系统支持,还会使用内存映射技术来增强性能. 语法:file_get_contents(path,include_pat

  • 用PHP ob_start()控制浏览器cache、生成html实现代码

    输出控制函数不对使用 header() 或 setcookie(), 发送的文件头信息产生影响,只对那些类似于 echo() 和 PHP 代码的数据块有作用. 我们先举一个简单的例子,让大家对Output Control有一个大致的印象: Example 1. PHP代码 复制代码 代码如下: <? ob_start(); //打开缓冲区 echo "Hello\n"; //输出 header("location:index.php"); //把浏览器重定向到

  • php基于ob_start(ob_gzhandler)实现网页压缩功能的方法

    本文实例讲述了php基于ob_start('ob_gzhandler')实现网页压缩功能的方法.分享给大家供大家参考,具体如下: PHP生成网页后传送给浏览器显示 ,页面的打开速度除了与用户的网速有关,往往也跟页面的大小有很关系,我们可以从网 页大小着手,以提高网页的响应速度. 下面的代码是一个压缩网页的例子,我们利用ob_gzip函数,使用ob_start将输出内容压缩后放到"缓冲区"后再输出 . PHP代码 //启用压缩 if(function_exists('ob_gzip'))

  • php中ob(Output Buffer 输出缓冲)函数使用方法

    来自:http://bbs.phome.net/ShowThread/?threadid=9247&forumid=2  在PHP编程中,  我们经常会遇到一些直接产生输出的函数,  如passthru(),readfile(),  var_dump()  等.  但有时我们想把这些函数的输出导入到文件中,或者先经过处理再输出,  或者把这些函数的输出作为字符串来处理.    这时我们就要用到  Output  Buffer(输出缓冲)  函数了. 处理输出缓冲的函数主要有这么几个:    ob

随机推荐