header()必须在任何实际输出之前调用,但是我们程序已经输出了,却正常运行。在看下面的代码:
<?phpecho "南无阿弥陀佛<br>";
ob_flush();
header("content-type:text/html;charset='utf-8'");echo "真善忍好!";//output//南无阿弥陀佛//Cannot modify header information - headers already sent by (output started at E:\php\test.php:3)//真善忍好
上面程序说明程序并没有立即输出,而当调用ob_flush 函数的时候才刷新缓冲,输出。
ob_flush() 与 flush()
ob_flush() , flush() 函数php 手册上都有详细的说明,你可以去查阅一下。二者的区别是:
ob_flush() 是刷新PHP自身的缓冲区
flush()是 它是刷新WebServer 服务器的缓冲。输出到浏览器。但是会出现下面的情况:
个别web服务器程序,特别是Win32下的web服务器程序,在发送结果到浏览器之前,仍然会缓存脚本的输出,直到程序结束为止。
有些Apache的模块,比如mod_gzip,可能自己进行输出缓存,这将导致flush()函数产生的结果不会立即被发送到客户端浏览器。
甚至浏览器也会在显示之前,缓存接收到的内容。例如 Netscape 浏览器会在接受到换行或 html 标记的开头之前缓存内容,并且在接受到 </table> 标记之前,不会显示出整个表格。
一些版本的 Microsoft Internet Explorer 只有当接受到的256个字节以后才开始显示该页面,所以必须发送一些额外的空格来让这些浏览器显示页面内容。
比如:
<?php/**
Server:LightTPD/1.4.28 (Win32)
X-Powered-By:PHP/5.3.27
*/echo '佛法无边'."<BR>";
ob_flush();
flush();
sleep(1);echo '法轮常转';//output
上面的代码 在 chrome 浏览器上面 是一行一行的输出,在ie系列的浏览器则是全部输出。其实就是上面的 第四条一些浏览器只有当接收256个字符才开始显示。把上面的代码改成下面形式:
<?php/**
Server:LightTPD/1.4.28 (Win32)
X-Powered-By:PHP/5.3.27
*/echo str_pad('',240)."\n";
echo '佛法无边'."<BR>";
ob_flush();
flush();
sleep(1);echo '法轮常转';//output
这样在ie下面就会一行一行输出,因为超过256个字符。
ob 其他函数说明
1.ob_end_flush 与 ob_end_clean
end 的顾名思义就结束,关闭缓冲区,都是关闭输出缓冲,一个是输出缓冲区,一个是清除。比如
<?php/**
Server:LightTPD/1.4.28 (Win32)
X-Powered-By:PHP/5.3.27
*/echo 'before';
ob_end_clean();echo str_pad('',4096)."\n";for ($i=10; $i>0; $i--)
{
echo $i;
sleep(1);
}
上述代码是一下输出全部内容,而不是一个一个输出。ob_end_clean()
不是关闭了缓冲了?怎么不是一个一个输出呢,其实我们上面也说了,php 不是直接输出给浏览器,而是 web server。 虽然php 没有了
缓冲。但是web server 还是有的。所以下面代码:
/**
Server:LightTPD/1.4.28 (Win32)
X-Powered-By:PHP/5.3.27
*/echo 'before';
ob_end_clean();echo str_pad('',4096)."\n";for ($i=10; $i>0; $i--)
{
flush(); echo $i;
sleep(1);
}
加上flush(),就会一行一行输出。 如果把ob_end_clean 换成 ob_end_flush 会把 before 输出来。
其他函数 可参考手册,比较简单。
总结
php 脚本到浏览器,要经过 php buffer=》web server buffer=》browser buffer。
最后显示到浏览器。 缺一不可。 所以我们要 ob_flush 和 flush 以及加上 echo str_pad(”,4096)
才能调试出你想要的效果。