php 輸出快取的魅力
一:輸出快取介紹
在php所謂的輸出緩存,就是程式碼中的echo 或其他輸出指令在執行的時候是先寫入到php buffer,在腳本執行完或強制執行輸出快取的指令後,才會把資料輸出到瀏覽器(其中php buffer 就是php.ini設定的output_buffering ,預設是on,表示無限大小,可以換成數字來限制大小)。
例子:
echo 'hlmblog.com';
echo '技術';
echo '分享';
這兩個echo 是依序插入到緩衝區的,只有腳本執行完成或強制執行輸出才會把資料輸出到瀏覽器。
如果我想要即時輸出echo的數據,請參閱下面的程式碼:
我想要即時輸出echo的數據,請參閱下面的程式碼:
ob_end_flush(); //關閉php緩存,或在flush ()前先執行ob_flush(),下面有解釋
echo str_pad(" ", 256);
for ($i=5; $i>0; $i--) {
echo $i. '
';
flush();
sleep(1);
}
注意:
注意:
1:flush和ob_ush 說明模凌兩可,其實兩者是有很大差別的。
當php.ini沒有開啟php buffer快取時,php腳本輸出的內容都會在服務端處於等待輸出狀態,不會儲存到輸出緩存,因為快取都沒開,此時利用flush可以將那些等待輸出的內容立即輸出來發送到客戶端(瀏覽器或其他輸出端)。
當php.ini開啟了php buffer快取後,php腳本輸出內容的第一步是儲存在輸出快取中,此時等到輸出的內容是沒有資料的,用flush的話是無效果,取不到資料的。因此要先利用ob_flush把輸出快取中的內容取出來變成等待輸出的狀態,接下來在利用flush把內容髮到客戶端。執行的順序是先ob_flush 再 flush。
因此要實現即時地輸出,要嘛利用ob_end_flush 先關掉php 輸出快取後直接flush,要嘛先 ob_flush再flush。
2:瀏覽器無法輸出即時資料
把程式碼改成下面的程式碼,在chrome firefox ie等瀏覽器都是一次性輸出的,很奇葩的現象:
ob_end_flush(); //關閉php緩存,或者在flush前ob_flush();
echo str_pad(" ", 256);
for ($i=5; $i>0; $i--) {
echo $ );
}
找了半天的bug,終於發現了個現象,只要順便加個html標籤,即可即時輸出。
原因是:只有在遇到html標籤的時候才會即時輸出,真是神奇,還好一般輸出的內容都會帶著html標籤,很少純文字。
解決方法:加個回車或其他的html標籤即可解決問題。
二:控制快取輸出可以用來做什麼,具體的幾個範例
1:產生靜態頁面
靜態頁面的載入速度就是快,這句話是家戶喻曉的道理,不用請求資料庫,這是多麼爽的事情啊。
以下是產生靜態頁面的範例:
echo str_pad('', 1024);//讓緩衝區溢位
ob_start();//開啟緩衝區
$content = ob_get_contents();//取得頁面輸出的內容
$f = fopen('./index.html', 'w');
fwrite($f, $content);//內容寫入檔案
fclose($f);
ob_end_clean();/ /清空並關閉緩衝區
傳說中的靜態頁面就這樣簡單的生成。
2:捕獲輸出
function test($param) {
if($param) {
ob_start();
eval($param); ob_end_clean();
}else {
echo '遺憾的沒有輸出';
exit();
}
return $contents;
}