首頁 >後端開發 >php教程 >php函式ob_start()控制瀏覽器cache的方法詳解

php函式ob_start()控制瀏覽器cache的方法詳解

WBOY
WBOY原創
2016-07-25 08:57:301112瀏覽
  1. ob_start(); //開啟緩衝區
  2. echo "Hellon"; //輸出
  3. header("location:indexer("location:index .php"); //把瀏覽器重新導向到index.php
  4. ob_end_flush();//輸出全部內容到瀏覽器
  5. //by bbs.it-home.org
  6. ?>
複製程式碼

這裡用到了php的header函數,這個函數會傳送一段檔案頭給瀏覽器,但是如果在使用這個函數之前已經有了任何輸出(包括空輸出,例如空格,回車和換行)就會提示出錯。 去掉第一行的ob_start(),再執行此程序,會有錯誤提示:"Header had all ready send by"! 加上ob_start,則不會提示出錯,原因在於當開啟了緩衝區,echo後面的字元不會輸出到瀏覽器,而是保留在伺服器,直到你使用flush或ob_end_flush才會輸出,所以不會有任何文件頭輸出的錯誤!

下面開始今天的主題內容:用ob_start()控制瀏覽器的cache快取。

一、 相關函數簡介: 1、Flush:刷新緩衝區的內容,輸出。 函數格式:flush() 說明:這個函數經常使用,效率很高。

2、ob_start :開啟輸出緩衝區 函數格式:void ob_start(void) 說明:當緩衝區啟動時,所有來自PHP程式的非檔案頭資訊均不會傳送,而是保存在內部緩衝區。為了輸出緩衝區的內容,可以使用ob_end_flush()或flush()輸出緩衝區的內容。

3 、ob_get_contents :傳回內部緩衝區的內容。 使用方法:string ob_get_contents(void) 說明:這個函數會傳回目前緩衝區中的內容,如果輸出緩衝區沒有激活,則傳回 FALSE 。

4、ob_get_length:傳回內部緩衝區的長度。 使用方法:int ob_get_length(void) 說明:這個函數會傳回目前緩衝區中的長度;和ob_get_contents一樣,如果輸出緩衝區沒有啟動。則回傳 FALSE。

5、ob_end_flush :傳送內部緩衝區的內容到瀏覽器,並且關閉輸出緩衝區。 使用方法:void ob_end_flush(void) 說明:這個函數會傳送輸出緩衝區的內容(如果有的話)。

6、ob_end_clean:刪除內部緩衝區的內容,並且關閉內部緩衝區 使用方法:void ob_end_clean(void) 說明:這個函數不會輸出內部緩衝區的內容而是刪除它!

7、ob_implicit_flush:開啟或關閉絕對刷新 使用方法:void ob_implicit_flush ([int flag]) 說明:使用過Perl的人都知道$|=x的意義,這個字串可以打開/關閉緩衝區,而ob_implicit_flush函數也和那個一樣,預設為關閉緩衝區,打開絕對輸出後,每個腳本輸出都直接傳送到瀏覽器,不再需要呼叫flush()

二、深入了解: 1. 關於Flush函數: 用於刷新browser的cache。

例:

  1. for($i = 1; $i / / 關鍵語句,cache的結構使得它的內容只有達到一定的大小才能從瀏覽器裡輸出
  2. // 換言之,如果cache的內容不達到一定的大小,它是不會在程式執行完畢前輸出的。經
  3. // 過測試,我發現這個大小的底限是256個字元長。這表示cache以後接收的內容都會
  4. // 源源不絕的被送出去。
  5. For($j = 1; $j echo $j."
  6. ";
  7. flush(); //這一部會使cache新增的內容被擠出去,顯示到瀏覽器上
  8. sleep(1); //讓程式"睡"一秒鐘,會讓你把效果看得更清楚
  9. }
  10. ?>
複製程式碼

註:如果在程式的首部加入ob_implicit_flush()開啟絕對刷新,就可以在程式中不再使用flush()。

2. 關於ob系列函數: 例如用得到伺服器和客戶端的設定訊息,但是這個資訊會因為客戶端的不同而不同,如果想要保存phpinfo()函數的輸出怎麼辦呢? 在沒有緩衝區控制之前,可以說一點辦法也沒有,但是有了緩衝區的控制,可以輕鬆的解決: 例子:

  1. ob_start(); //開啟緩衝區
  2. phpinfo(); //使用phpinfo函數
  3. $info =ob_get_contents(); //得到緩衝區的內容並且賦值給$info
  4. $file=fopen('info.txt','w'); //開啟檔案info.txt
  5. fwrite($file ,$info); //寫入訊息到info.txt
  6. fclose($file); //關閉檔案info.txt
  7. //by bbs.it-home.org
  8. ?>
複製程式碼

用以上的方法,就可以把不同使用者的phpinfo資訊保存下來,這在以前恐怕沒有辦法辦到!其實上面就是將一些"過程"轉換為"函數"的方法! PHP預設的語法加亮顯示函數會直接輸出,不能儲存結果,如果每次呼叫都顯示恐怕會很浪費CPU。

ob_start()的要點。 .使用ob_start開啟browser的cache,這樣可以確保cache的內容在你呼叫flush(),ob_end_flush()(或程式執行完畢)之前不會被輸出。 .現在的你應該知道你所擁有的優點:可以在任何輸出內容後面使用header,setcookie以及session,這是ob_start一個很大的特點;也可以使用ob_start的參數,在cache被寫入後,然後自動執行指令,例如ob_start("ob_gzhandler");而我們最常用的做法是用ob_get_contents()得到cache中的內容,然後再處理… .當處理完畢後,我們可以使用各種方法輸出,flush(),ob_end_flush(),以及等到程式執行完畢後的自動輸出。當然,如果你用的是ob_get_contents(),那麼就要你自己控制輸出方式了。

下面來學習下ob系列函數的用法。

一、 靜態模版技術 簡介:所謂靜態模版技術就是透過某種方式,使得使用者在client端得到的是由PHP產生的html頁面。如果這個html頁面不會再更新,那麼當另外的使用者再次瀏覽此頁面時,程式將不會再呼叫PHP以及相關的資料庫,對於某些資訊量比較大的網站,例如sina,163,sohu。類似這種的技術帶來的好處是非常巨大的。

實作靜態輸出的有兩種方法: .經由y10k修改的phplib的一個叫做template.inc.php類別實作。 .使用ob系列函數實作。 對於第一種方法,因為不是這篇文章所要研究的問題,所以不再贅述。 現在來看看第二種方法的具體實作: 例子:

  1. ob_start();//開啟緩衝區>
  2. ?>
複製程式碼

php頁面的全部輸出:

  1. $content = ob_get_contents();//取得php頁面輸出的全部內容
  2. $fp = fopen("output00001. html", "w"); //建立一個文件,並且打開,準備寫入
  3. fwrite($fp, $content); //把php頁面的內容全部寫入output00001.html,然後…
  4. fclose($fp);
  5. //by bbs.it-home.org
  6. ?>
複製程式碼

二、 捕捉輸出 以上的例子是一種最簡單的情況,還可以在寫入前對$content進行操作等。 可以設法捕捉一些關鍵字,然後去對它進行再處理,例如PHP語法高亮顯示。 例5:

  1. Function run_code($code) {
  2. If($code) {
  3. ob_start();
  4. If($code) {
  5. ob_start();
  6. eval ($code);
  7. $contents = ob_get_contents();
  8. ob_end_clean();
  9. }else {
  10. echo "錯誤!沒有輸出";
  11. exit();
  12. echo "錯誤!沒有輸出";
  13. exit();
}
return $contents;}
複製程式碼

以上這個例子的用途不是很大,不過很典型$code的本身就是一個含有變數的輸出頁面,而這個例子用eval把$code中的變數替換,然後對輸出結果再進行輸出捕捉,再一次的進行處理…

例6,加快傳輸

  1. ** ------------Start of file---- ------
  2. ** |
  3. ** | include('gzdoc.php');
  4. ** |? >
  5. ** |
  6. * * |... the page ...
  7. ** |
  8. ** |
  9. ** | gzdocout();
  10. ** |? >
  11. * * -------------End of file-----------
  12. */
  13. ob_start();

  14. ob_implicit_flush(0);
  15. function CheckCanGzip(){
  16. global $HTTP_ACCEPT_ENCODING;
  17. if (headers_sent() || connection_timeout() ||.
  18. if (strpos($HTTP_ACCEPT_ENCODING, 'x-gzip') !== false) return "x-gzip";

  19. if (strpos($HTTP_ACCEPT_ENCODING,'gzip') ! == false) return "gzip";
  20. return 0;
  21. }
  22. /* $level = compression level 0-9, 0=none, 9=max */

  23. function GzDocOut($level=1,$debug=0){
  24. $ENCODING = CheckCanGzip();
  25. if ($ENCODING){
  26. print "n
陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn