首页 > 代码库 > PHP输出缓冲

PHP输出缓冲

PHP输出缓冲

2017-03-02 22:41:04

  首先要了解的是,PHPweb服务器(apache服务器)以及浏览器都有自己的缓冲区(buffer),这三者输出数据前都会先把要输出的数据保存到自身的缓冲区,待自身的缓冲区被数据填满或者存储了一定量的数据之后,就会把数据输出来【注:各个浏览器的缓冲区要求存储的数据量不同,IE256Bytes, ChromeFireFox1000Bytes,只有输出数据达到了这个长度或者脚本结束浏览器才会将数据输出在页面上】。
PHP程序输出内容(echoprint_r …)到浏览器总共有以下步骤:

echoprint => php output_buffering => webServer buffer => browser buff => browser display

即:脚本输出 => php的缓冲区设置 => 系统的缓冲区设置(apachenginx) => 浏览器的缓冲区设置 => 显示给用户

具体步骤如下如下图所示
技术分享

PHP缓冲区(PHP Buffer

  php运行的结果先放入缓冲区(buffer),只有当缓冲区满了或者php运行完毕,才将数据输出去。
  缓冲区开关是通过php.ini中的output_buffering变量控制。在php.ini中,我们可以设置output_buffering为大于0的数值来打开buffer。此外我们可以设置“output_buffering=off”来关闭php缓冲区,然后通过ob_start()函数来开启php缓冲区。【注:ini_set()函数无法修改php buffer的设置】
  大家都说:ob_start()是将php buffer打开,ob_end_flush()是将php buffer关闭。需要注意的是如果php.iniphp buffer是关闭的,再次调用ob_end_flush()会报warning

web服务器缓冲区(Webserver buffer

  这里只讲apache服务器的缓冲区。
  当php的输出数据给apache服务器时,它也会做一层buffer(也将数据放入它的缓冲区,当缓冲区数据满或执行完毕时,才输出数据)。若想关闭缓冲区,可以在php层使用flush()来强制将缓冲区数据从apache缓冲区输出。
  flush() 的工作原理:在apache modulesapi, flush会通过调用sapi_moduleflush成员函数指针, 间接的调用apacheapi: ap_rflush刷新apache的输出缓冲区。 当然手册中也说了, 有一些apache的其他模块, 可能会改变这个动作的结果,例如mod_gzip:可能自己进行输出缓冲区,这将导致flush()函数产生的结果不会立即被发送到客户端浏览器。

浏览器缓冲区(Browser buffer

  浏览器从服务器接收的数据不会直接显示,而会先将数据保存在浏览器缓冲区,等到保存的数据达到一定的长度时(不同浏览器长度不同,IE256Bytes, ChromeFireFox1000Bytes),浏览器的缓冲区就相当于填满,只有数据达到了这个长度或者脚本结束浏览器才会将数据输出在页面上。
  在php中无法控制浏览器的缓冲区的开关,如果希望输出数据不受浏览器缓冲区的影响,可以先发送一些空格来填满浏览器的buffer,浏览器的buffer一满,就会将其他新输出的数据不经过缓冲区直接输出。
  但是不同的浏览器会设置不同的buffer大小。为了保险期间,可以发送4096个空格,因为目前比较流行的浏览器的buffer还没有超过4k(一个内页大小)
  在php.ini中关闭php缓冲区的前提下,我们可以在apache服务器下执行以下代码来探究以上讨论的三者缓冲区
 1 <?php
 2          ob_start();                            #开启php缓冲区
 3          echo str_repeat(‘&nbsp;‘, 4096);       #填满浏览器的缓冲区,以便浏览器可以直接输出之后的内容
 4          echo ‘<br>‘;
 5 
 6          for ($i=0; $i < 5; $i++) {
 7                    echo $i,‘<br>‘;
 8                    //ob_flush();      #刷新php缓冲区,是数据不在php缓冲区停留,直接输出
 9                    flush();           #刷新(冲刷)web服务器的缓冲区,这里可以特指apache的缓冲区
10                    sleep(1);          #暂停1秒
11          }
12 ?>

参考来源:http://blog.csdn.net/fwkjdaghappy1/article/details/25402809

PHP输出缓冲