偶然機會看到了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()才能獲取到