在PHP中,当执行echo,print的时候,输出并没有立即通过tcp传给客户端浏览器显示, 而是将数据写入php buffer。php output_buffering机制,意味在tcp buffer之前,建立了一新的队列,数据必须经过该队列。当一个php buffer写满的时候,脚本进程会将php buffer中的输出数据交给系统内核交由tcp传给浏览器显示。所以,数据会依次写到这几个地方echo/pring -> php buffer -> tcp buffer(apache,nginx,lightHTTP) -> browser buffer
ob_*系列函数, 是操作PHP本身的输出缓冲区。即, ob_flush是刷新PHP自身的缓冲区.
而flush, 它是刷新WebServer(可以认为特指apache)的缓冲区.
有些Apache的模块,比如mod_gzip,可能自己进行输出缓存,这将导致flush()函数产生的结果不会立即被发送到客户端浏览器。
浏览器也会在显示之前,缓存接收到的内容。例如 Netscape浏览器会在接受到换行或 html 标记的开头之前缓存内容,并且在接受到 标记之前,不会显示出整个表格。
浏览器的输出缓存:IE为256Bytes, Chrome与FireFox为1000Bytes,只有输出数据达到了这个长度或者脚本结束浏览器才会将数据输出在页面上,但一些版本的 Microsoft Internet Explorer 只有当接受到的256个字节以后才开始显示该页面,所以必须发送一些额外的空格来让这些浏览器显示页面内容。
因此需要正确使用俩者的顺序,先ob_flush, 然后flush。当然, 在其他sapi下, 不调用flush也可以, 只不过为了保证你代码的可移植性, 建议配套使用。
<?php
ob_start();
for ($i = 100; $i > 85; $i--)
{
echo str_pad(" ", $i)."$i<br/>";
ob_flush();
flush();
sleep(1);
}
?>