PHP 代码
$str = ‘Hello world”;
echo $str;
sleep(10);
这段代码会在sleep了10秒后在页面打印 Hello world。在看下面这段代码:
PHP 代码
$str = ‘Hello world”;
echo $str . str_repeat(’ ‘, 256);
ob_flush();
flush();
sleep(10);
这段代码则会马上在屏幕上打印 Hello world。关键就在于第2和第3行调用的两个函数 ob_flush() 和
flush()。这两个函数得一起使用才能保证页面马上输出Hello world。其中str_repeat(’ ‘,
256)则是为了解决某些浏览器必须在接收到256个字符后才会显示内容。下面的内容摘自《PHP用户手册》,很好地解释了上面的代码意图。
引用自《PHP用户手册》的内容
flush() 函数不会对服务器或客户端浏览器的缓存模式产生影响。因此,必须同时使用 ob_flush() 和flush() 函数来刷新输出缓冲。
个别web服务器程序,特别是Win32下的web服务器程序,在发送结果到浏览器之前,仍然会缓存脚本的输出,直到程序结束为止。
有些Apache的模块,比如mod_gzip,可能自己进行输出缓存,这将导致flush()函数产生的结果不会立即被发送到客户端浏览器。
甚至浏览器也会在显示之前,缓存接收到的内容。例如 Netscape 浏览器会在接受到换行或 html 标记的开头之前缓存内容,并且在接受到 标记之前,不会显示出整个表格。
一些版本的 Microsoft Internet Explorer 只有当接受到的256个字节以后才开始显示该页面,所以必须发送一些额外的空格来让这些浏览器显示页面内容。
上面的代码演示了即时输出缓存,一般情况下该部分代码都能正常完成所要的功能,但是也会有例外
1)服务器打开了gzip等压缩功能,导致输出的缓存被压缩后不足256字节,那么在某些版本IE中也会等到凑够了256字节才输出内容(PS:之所以说某些版本的IE是因为我现在用的IE6就没有该问题,WINDOWS
XP SP2)
2)如果这段代码之前还有代码,而且前面的代码中多次调用了
ob_start()而ob_end_flush()调用的次数比ob_start()少2次,那么这上面的代码也不能正常工作。因为
ob_start()的buffer是stackable的。调用多次ob_start()后,ob_flush()只会把buffer输出到上一层的
buffer中。例如
调用ob_start(),它的缓存区为
buffer1,再次调用ob_start(),它的缓存区为buffer2。这时调用ob_flush()只会把
buffer2中的内容输出到 buffer1。这时如果调用 ob_end_flush(), 那么buffer2中的内容会被输出到
buffer1并且销毁buffer2。此时再调用ob_flush()就会把buffer1中的内容输出到服务器,然后调用flush()则可以把服务
器中的buffer输出到客户端浏览器。
知道了ob_start()和ob_end_flush()的用法后,就可以用下面的代码来实现所有页面内容完全生成后一次性输出所有的缓存。
PHP 代码
ob_start();
//do something to generate $content
echo $content;
ob_end_flush();
flush(); //if script is ending, this can be removed.
之所以要这么做是因为服务器会在缓存区满了以后就输出缓存而不是等到所以页面内容生成后再输出