1.缓冲区作用:把输入或者输出的内容先放进内存,而不显示或者读取;
2.当执行PHP的时候,如果碰到了echo print_r之类的会输出数据的代码,PHP就会将要输出的数据放到PHP自身的缓冲区,等待输出。当PHP自身的缓冲区接到指令,指示要输出缓冲区的内容时,将会把缓冲区内的数据输出到Apache上, A接收到PHP输出的数据,然后再把该数据存到Apache自身的缓冲区内,等待输出。当Apache接受到输出缓冲区的内容的指令时, 将会把缓冲区的内容输出,返回到浏览器PHP输出数据。过程如下:
![](https://img-blog.csdn.net/20170804113336703?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvb25seWppbg==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
缓冲区在PHP中常见操作:
1.防止header头部报错:
在使用header函数之前,就已经输出了某些数据,这样会导致某些错误,而header函数是不受缓冲区影响的,当使用header函数时,PHP向Apache发送一个http报头到浏览器,而需要输出的数据并不显示,只是打开输出缓冲区,把这些数据将存放在缓冲区,等待输出.这样就可以避免了之前所发生的错误。
2.通过PHP完成文件下载时避免文件过大响应满,影响内存等:
当使用fwrite把文件内容读出并显示,然后通过header来发送HTTP头的方法进行文件下载时,如果一个文件很大,假设为100M,那么在不开启缓冲区输出的情况下,必须要把100M数据全部读出,然后一次返回到页面上。如果这样做,一方面用户将会在所有数据读完之后才会得到响应,降低了用户体验感。另一方面,,需要把100M文件全部读入内存,然后再输出,这样占用了大量内存,当程序做了内存限制,这些操作将无法完成。
如果开启了输出缓冲区,可以使用循环语句分段读取文件,每次读取完毕存入缓冲区输出到Apache,然后让Apache返回浏览器显示,直到把文件全部输出为止,这样浏览器就可以持续地接受到数据,而不必等到所有文件读取完毕。减少用户等待时间。
3.静态页面缓存:
静态页面缓存是常用方法,生产的数据信息一方面展示在浏览器,一方面存入服务器缓存文件夹,一定时间内直接访问生成的静态页面文件。通过缓存来显著地提高系统的扩展能力,改善系统的响应能力,同时减少系统的负担等。
1)php.ini关于缓冲区的配置:
a) output_buffering 该项配置php自身缓冲区:
on - 开启缓冲区
off - 关闭缓冲区
256k - 开启缓冲区,而且当缓冲区的内容超过256k的时候,自动刷新缓冲区(把数据发送apache);
b) implicit_flush 该项配Apache自身缓冲区:
on - 开启缓冲区
off - 关闭缓冲区
2)与缓冲区有关的函数
flush ---发送指令到apache,让apache刷新自身的输出缓冲区.
ob_implicit_flush ---是否自动刷新apache的缓冲区
ob_start ---打开输出缓冲区,即使output_buffering设置成off,也会打开输出缓冲区
ob_flush ---指示php本身刷新自身的缓冲区,把数据发送到apache
ob_end_flush ---把php自身的缓冲区里的内容发送到apache,并把清除自身缓冲区内的内容
ob_get_contents ---获取输出缓冲区里的内容
ob_get_flush ---获取缓冲区里的内容,并且把这些内容发送到apache
ob_clean ---清除php缓冲区里面的内容
ob_get_clean ---获取缓冲区的内容之后,清除缓冲区.
ob_end_clean ---清除php缓冲区内的内容,并且关闭输出缓冲区
ob_get_length ---获取缓冲区里内容的长度
ob_list_handlers ---获取运行ob_start时,所回调的函数名称, 例如:ob_start(‘ob_gzhandler’);print_r(ob_list_handlers);将打印出ob_gzhandler;
ob_gzhandler ---该函数的作用是作为ob_start的回调参数, 在缓冲区刷新之前,会调用该函数对数据进行到底gzip或者deflate压缩.这个函数需要zlib扩展的支持.
使用缓冲区的相关内容
1.ob_flush和flush的次序关系.上面的分析可以看出,ob_flush是和php自身相关的,而flush操作的是apache的缓冲区,所有我们在使用这两个函数的时候,需要先执行ob_flush,
再执行flush,因为我们需要先把数据从PHP上发送到apache,然后再由apache返回到浏览器.如果php还没有把数据刷新到apache,就调用了flush,则apache无任何数据返回到浏览器.
2.有的浏览器,如果接受到的字符太少,则不会把数据显示出来,例如老版的IE(必须要大于256k才显示).这样就会造成一个疑问, 明明在php和apache都进行了刷新缓冲区的操作,但是浏览器就是没有出现自己想要的数据,也许就是这个原因造成的.所以才测试的时候,可以在输出数据的后面加上多个空格,以填满数据,确定不会浏览器造成这类诡异的问题.
3.有些webserver,他自身的输出缓冲区会有一些限制,比如nginx,他有一个配置fastcgi_buffer_size 4k, 就是是表明,当自身的输出缓冲区的内容达到4K才会刷新,所以为了保证内容的数据,可以添加以下代码,保证内容长度
str_repeat(' ',4096);
4.在apache中,如果你开启了mod_gzip的压缩模块,这样可能会导致你的flush函数刷新不成功,其原因是,mod_gzip有自己的输出缓冲区,当php执行了flush函数,指示apache刷新输出缓冲区,但是内容需要压缩,apache就把内容输出到自身的mod_gzip模块,mod_gzip也有自身的输出缓冲区,他也不会马上输出,所以造成了内容不能马上输出.为了改善这个情况,可以关闭mod_gzip模块,或者在httpd.conf增加以下内容,以禁止压缩
SetEnv no-gzip dont-vary
参考原文链接:http://www.cnblogs.com/saw2012/archive/2013/01/30/2882451.html