偶然机会看到了flush()。知道他的神奇功能能够用在异步传输的comet 模式以后,因而我去试了试这个方法。而后翻手册去看了看什么意思。发现它神奇的和ob类函数在一块儿。有点好奇,先放一放,来讲flush的做用。php
手册上面这样说:web
flush() may not be able to override the buffering scheme of your web server and it has no effect on any client-side buffering in the browser. It also doesn't affect PHP's userspace output buffering mechanism. This means you will have to call both ob_flush() and flush() to flush the ob output buffers if you are using those. 浏览器
我蹩脚地翻译一下缓存
flush()函数可能没法覆盖您的Web服务器的缓冲方案,它也不能影响任何客户端浏览器中的缓存。它也不会影响PHP的用户态输出缓冲机制,这意味着,若是你使用ob,你将不得不一样时ob_flush()和flush()来刷新OB输出缓冲区。服务器
好,如今可能暂时并非很理解这个究竟是神马意思,不要紧。先来看flush函数。异步
访问以下代码ide
<?php $i = 0; for($i;$i<10;$i++){ echo $i; flush(); sleep(2); }
我用的firefox访问的,尽然一直转,没有输出,一直运行了二十秒,我擦,不是说直接输出么。 好吧,我又蛋疼了。。而后打开firebug 看下network,继续刷页面,神奇的事情就发生了,竟然一刷就有响应,而且响应是一步一步出来的每隔2秒钟多一个数字,看来PHP没坑咱们。同时回顾他手册上说的 : 它也不能影响任何客户端浏览器中的缓存。恩,大概也就明白了,firefox也是有必定的缓存机制,没有遇到响应结束符号的时候是不会输出的。一样:函数可能没法覆盖您的Web服务器的缓冲方案。这个也可以明白一点点,也就是若是web服务器存在缓冲区的话应该也是不可以这样响应的。函数
OK,flush这个神奇的函数就搞定了。spa
突发奇想,不如用ob_flush来试一试行不行。.net
1 <?php 2 $i = 0; 3 for($i;$i<10;$i++){ 4 echo $i; 5 ob_flush(); 6 sleep(2); 7 }
发现屁用没有,直接就输出了。不都是输出缓冲区么。
继续看一看手册,ob全在那里,确实让人蛋疼。在ob_start里面明确说明了一点:
This function will turn output buffering on. While output buffering is active no output is sent from the script (other than headers), instead the output is stored in an internal buffer.
翻译一下:
此功能将开启输出缓冲。虽然输出缓冲区是存活的将不会有任何信息从脚本输出,而不是从脚本(标头之外)的输出被存储在内部缓冲器中。
通过他这么一说貌似好像ob的output buffering好像和那个并非一个东西。 据我理解,自己php就是用缓冲的,好比不管咱们是最开始的时候仍是最后的时候echo something,老是到了脚本执行完了以后才会输出。这一点本身求证过。然而这种系统级别的缓冲并不能知足咱们的须要,好比蛋疼的生成静态,好了伤心事不提。因此提供了一个ob的函数库来管理,(备注:ob是能够堆栈调用的。也就是嵌套)。固然只是猜测。运行以下代码:
1 <?php 2 $i = 0; 3 ob_start(); 4 for($i;$i<10;$i++){ 5 echo $i; 6 $content .= ob_get_contents(); 7 ob_flush(); 8 flush(); 9 sleep(2); 10 } 11 echo '<br />'; 12 echo $content;
这样的代码应该就能够说明一些问题了。结果输出前十个数慢慢输出,最后十个脚本执行完成后输出,一次性。结果和预期同样。说明ob和flush不是在一层。显然也就证实了手册上面的:它也不会影响PHP的用户态输出缓冲机制,这意味着,,你将不得不一样时ob_flush()和flush()来刷新OB输出缓冲区。若是你只使用了flush,若是你的浏览器返回 重载页面以获取资源的话那么说明你的flush被web server缓存了,也就是说你必须同时使用ob_flush()和flush()才能获取到