php输出数据到页面上,比如echo "11111111";然后程序中还有其他的输出,如果没有开启缓冲区,就是有echo , print ==一系列的打印方法,就会往浏览器器上输出,但是有了缓冲区之后就不一样了。先填充缓冲区,缓冲区填满了再输出到页面上,我在网上找了一些相关的介绍,记录下来...........
buffer是一个内存地址空间,Linux系统默认大小一般为4096(4kb),即一个内存页。主要用于存储速度不同步的设备或者优先级不同的设备之间传办理数据的区域。通过buffer,可以使进程这间的相互等待变少。这里说一个通俗一点的例子,你打开文本编辑器编辑一个文件的时候,你每输入一个字符,操作系统并不会立即把这个字符直接写入到磁盘,而是先写入到buffer,当写满了一个buffer的时候,才会把buffer中的数据写入磁盘,当然当调用内核函数flush()的时候,强制要求把buffer中的脏数据写回磁盘。
同样的道理,当执行echo,print的时候,输出并没有立即通过tcp传给客户端浏览器显示, 而是将数据写入php buffer。php output_buffering机制,意味在tcp buffer之前,建立了一新的队列,数据必须经过该队列。当一个php buffer写满的时候,脚本进程会将php buffer中的输出数据交给系统内核交由tcp传给浏览器显示。所以,数据会依次写到这几个地方echo/pring -> php buffer -> tcp buffer -> browser
在php.ini里面, output_buffering默认是开启的,默认值是4096字节,就是4kb,
; Development Value: 4096
; Production Value: 4096
; http://php.net/output-buffering
如果配置里面设置成 output_buffering = Off ,在程序中可以用ob_start()来开启缓冲区
另外还有一个配置
; automatically after every output block. This is equivalent to calling the
; PHP function flush() after each and every call to print() or echo() and each
; and every HTML block. Turning this option on has serious performance
; implications and is generally recommended for debugging purposes only.
; http://php.net/implicit-flush
; Note: This directive is hardcoded to On for the CLI SAPI
implicit_flush = Off
Off 每次输出后不会调用flush(),需要等到server buffering满了才会输出.
On 表示每次输出(如echo,print)后自动调用flush()函数后,直接输出
1.打开了php输出缓存: echo,print -> php output_buffring -> server buffering -> browser buffering -> browser display
2.未打开php输出缓存: echo,print -> server buffering -> browser buffering -> browser display
-
ob_start
Turn on output buffering
打开输出缓冲区
配置里面是关闭缓冲区的,或者认为的关闭了缓冲区,可以用该函数打开缓冲区
-
ob_get_contents
Gets the contents of the output buffer without clearing it
得到缓冲区的数据,但是不清空缓冲区,如果缓冲区没有激活,返回false
-
ob_get_clean
Get current buffer contents and delete current output buffer
得到缓冲区的数据,同时清空缓冲区
-
ob_get_length
This will return the length of the contents in the output buffer
返回缓冲区内容的长度,没有激活,返回false
-
ob_get_status
ob_get_status() returns status information on either the top level output buffer or all active output buffer levels if full_status is set to TRUE.
返回最顶层输出缓冲区的状态信息;或者如果full_status设为TRUE,返回所有有效的输出缓冲级别
这个不大懂, 关于缓冲区级别是什么样子的
-
ob_clean
Clean (erase) the output buffer
-
ob_end_clean
Clean (erase) the output buffer and turn off output buffering
关闭缓冲区,并且清空缓冲区
-
ob_end_flush
Flush (send) the output buffer and turn off output buffering
关闭缓冲区,并且输出缓冲区(应该是将php的buffer输出到server的buffer )
-
ob_flush
Flush (send) the output buffer
输出缓冲区(php的buffer输出到server的buffer)
-
flush
刷新PHP程序的缓冲,而不论PHP执行在何种情况下(CGI ,web服务器等等)。该函数将当前为止程序的所有输出发送到用户的浏览器。
取出Server buffering的数据,放入browser buffering
php的ob函数还有好几个,都没怎么用到,也不大懂是什么意思.........
以前看session的时候,有说在session_start()之前不能有任何的输出,不然会报告错误,但是我怎么也调试不出来,就是在session_start之前echo,不报错.当时别人告诉我是缓冲区开启了的原因,悲剧的是 我都不知道缓冲区是啥
ob_end_clean();
echo "1111111";
session_start();
Warning: session_start() [function.session-start]: Cannot send session cache limiter - headers already sent
在就是设置header头之前能有任何输出,其实这个也很好理解,输出表示请求和响应已经完成了,这是时候响应头也完毕,在去修改响应就不可能了
一个例子,看网上很举这个例子,来理解缓冲区
ob_start();
$i=10;
while($i>=0){
echo ($i--)."<br>";
sleep(1);
}
可以看到大概经过了10多秒,一下子将全部的数据打印到页面上的
在一个例子
ob_end_clean();
$i=10;
while($i>=0){
echo ($i--)."<br>";
sleep(1);
}
还是一次性输出在页面上
为啥?因为server还是有缓冲区的,当server端的缓冲区满了,才会向brower发送,所以要加上flush函数
在试试
ob_end_clean();
$i=10;
while($i>=0){
echo ($i--)."<br>";
flush();
sleep(1);
}
结果在我的浏览器上面还是一次性全部输出的
为啥?我也不知道为啥,网上看到的解释,也不是理解的很清楚 个别web服务器程序,特别是Win32下的web服务器程序,在发送结果到浏览器之前,仍然会缓存脚本的输出,直到程序结束为止。有些Apache的模块,比如mod_gzip,可能自己进行输出缓存,这将导致 flush()函数产生的结果不会立即被发送到客户端浏览器。甚至浏览器也会在显示之前,缓存接收到的内容。例如 Netscape 浏览器会在接受到换行或 html 标记的开头之前缓存内容,并且在接受到 </table> 标记之前,不会显示出整个表格。
根据前辈们的经验,ob_flush,flush同时使用,可以讲一段一段的输出到页面上
$i=10;
while($i>=0){
echo ($i--)."<br>";
ob_flush();
flush();
sleep(1);
}
我也看了有些技术blog的介绍,有些blog上说的跟我不一样,可能跟环境有关,反正我不懂的东西太多了
https://www.surfchen.org/archives/125
http://www.perfgeeks.com/?p=344
http://www.cnblogs.com/zemliu/archive/2012/05/11/2495293.html (这位兄弟些的个 和我测试的结果差不多)