ob的基本原則:如果ob緩衝開啟,則echo的資料首先放在ob緩衝。如果是header資訊,直接放在程式緩衝。當頁面執行到最後,會把ob緩衝的資料放到程式緩衝,然後依次返回給瀏覽器。
下面我說說ob的基本作用:
1)防止在瀏覽器有輸出之後再使用setcookie()、header()或session_start()等發送標頭檔的函數造成的錯誤。其實這樣的用法少用為好,養成良好的代碼習慣。
2)捕捉對一些不可擷取的函數的輸出,比如phpinfo()會輸出一大堆的HTML,但是我們無法用一個變數例如$info=phpinfo();來捕捉,這時候ob就管用了。
3)對輸出的內容進行處理,例如進行gzip壓縮,例如進行簡繁轉換,例如進行一些字串替換。
4)產生靜態檔案,其實就是捕捉整頁的輸出,然後存成檔案。經常在產生HTML,或者整頁緩衝中使用。
對於剛才說的第三點中的GZIP壓縮,可能是很多人想用,卻沒有真用上的,其實稍稍修改下代碼,就可以實現頁面的gzip壓縮。
複製代碼 代碼如下:ob_start(ob_gzhandler);
要緩衝的內容
沒錯,加一個ob_gzhandler這個回呼函數就可以了,不過這麼做有些小問題,一是需要zlib支援,二是沒有判斷瀏覽器是否支援gzip(現在好像都支援,iphone瀏覽器好像都支援了)。
以前的做法是判斷一下瀏覽器是否支援gzip,然後用第三方的gzip函數來壓縮ob_get_contents() 的內容,最後echo。
一、ob系列函數中常用函數集錦
複製代碼 代碼如下:
ob_start(); //開啟一個輸出緩衝區,所有的輸出資訊不再直接發送到瀏覽器,而是儲存在輸出緩衝區裡面。
ob_clean(); //刪除內部緩衝區的內容,不關閉緩衝區(不輸出)。
ob_end_clean(); //刪除內部緩衝區的內容,關閉緩衝區(不輸出)。
ob_get_clean(); //返回內部緩衝區的內容,關閉緩衝區。相當於執行 ob_get_contents() and ob_end_clean()
ob_flush(); //發送內部緩衝區的內容到瀏覽器,刪除緩衝區的內容,不關閉緩衝區。
ob_end_flush(); //發送內部緩衝區的內容到瀏覽器,刪除緩衝區的內容,關閉緩衝區。
ob_get_flush(); //返回內部緩衝區的內容,並關閉緩衝區,再釋放緩衝區的內容。相當於ob_end_flush()並返回緩衝區內容。
flush(); //將ob_flush釋放出來的內容,以及不在PHP緩衝區中的內容,全部輸出至瀏覽器;重新整理內部緩衝區的內容,並輸出。
ob_get_contents(); //返回緩衝區的內容,不輸出。
ob_get_length(); //返回內部緩衝區的長度,如果緩衝區未被啟用,該函數返回FALSE。
ob_get_level(); //Return the nesting level of the output buffering mechanism.
ob_get_status(); //Get status of output buffers.
ob_implicit_flush(); //開啟或關閉絕對重新整理,預設為關閉,開啟後ob_implicit_flush(true),所謂絕對重新整理,即當有輸出語句(e.g: echo)被執行時,便把輸出直接發送到瀏覽器,而不再需要調用flush()或等到指令碼結束時才輸出。
ob_gzhandler //ob_start回呼函數,用gzip壓縮緩衝區的內容。
ob_list_handlers //List all output handlers in use
output_add_rewrite_var //Add URL rewriter values
output_reset_rewrite_vars //Reset URL rewriter values
這些函數的行為受php_ini設定的影響:
output_buffering //該值為ON時,將在所有指令碼中使用輸出控制;若該值為一個數字,則代表緩衝區的最大位元組限制,當緩衝內容達到該上限時將會自動向瀏覽器輸出當前的緩衝區裡的內容。
output_handler //該選項可將指令碼所有的輸出,重新導向到一個函數。例如,將 output_handler 設定為 mb_output_handler() 時,字元的編碼將被修改為指定的編碼。設定的任何處理函數,將自動的處理輸出緩衝。
implicit_flush //作用同ob_implicit_flush,預設為Off。
二、執行個體講解
1、使 header() 函數前可以有echo代碼
Output Control 函數可以讓你自由控制指令碼中資料的輸出。它非常地有用,特別是對於:當你想在資料已經輸出後,再輸出檔案頭的情況。
輸出控制函數不對使用 header() 或 setcookie(),發送的檔案頭資訊產生影響,只對那些類似於 echo() 和 PHP 代碼的資料區塊有作用。
複製代碼 代碼如下:ob_start(); //開啟緩衝區
echo "Hello\n"; //輸出
header(“location:index.php”); //把瀏覽器重新導向到index.php
ob_end_flush(); //輸出全部內容到瀏覽器
所有對header()函數有瞭解的人都知道,這個函數會發送一段檔案頭給瀏覽器,但是如果在使用這個函數之前已經有了任何輸出(包括空輸出,比如空格,斷行符號和換行)就會提示出錯。如果我們去掉第一行的ob_start(),再執行此程式,我們會發現得到了一條錯誤提示:"Header had all ready send by"!但是加上ob_start,就不會提示出錯,原因是當開啟了緩衝區,echo後面的字元不會輸出到瀏覽器,而是保留在伺服器,直到你使用flush或者ob_end_flush才會輸出,所以並不會有任何檔案頭輸出的錯誤!
2、儲存 phpinfo() 函數的輸出
複製代碼 代碼如下:ob_start(); //開啟緩衝區
phpinfo(); //使用phpinfo函數
$info = ob_get_contents(); //得到緩衝區的內容並且賦值給$info
$file = fopen('info.txt', 'w'); //開啟檔案info.txt
fwrite($file, $info); //寫入資訊到info.txt
fclose($file); //關閉檔案info.txt
3、靜態模版技術
所謂靜態模版技術就是通過某種方式,使得使用者在client端得到的是由PHP產生的html頁面。如果這個html頁面不會再被更新,那麼當另外的使用者再次瀏覽此頁面時,程式將不會再調用PHP以及相關的資料庫,對於某些資訊量比較大的網站,例如sina、163、sohu。類似這種的技術帶來的好處是非常巨大的。
複製代碼 代碼如下:ob_start(); //開啟緩衝區
php頁面的全部輸出
$content = ob_get_contents(); //取得php頁面輸出的全部內容
$fp = fopen("output00001.html", "w"); //建立一個檔案,並開啟,準備寫入
fwrite($fp, $content); //把php頁面的內容全部寫入output00001.html,然後……
fclose($fp);
三、輸出緩衝控制代碼ob_gzhandler
PHP4.0.4有一個新的輸出緩衝控制代碼ob_gzhandler,它與前面的類相似,但用法不同。使用ob_gzhandler時要在php.ini中加入的內容如下:
複製代碼 代碼如下:output_handler = ob_gzhandler;
這行代碼使得PHP啟用輸出緩衝,並壓縮它發送出去的所有內容。
如果由於某種原因你不想在php.ini中加上這行代碼,你還可以通過PHP源檔案所在目錄的.htaccess檔案改變預設的伺服器行為(不壓縮),文法如下:
複製代碼 代碼如下:php_value output_handler ob_gzhandler
或者是從PHP代碼調用,如下所示:
複製代碼 代碼如下:ob_start("ob_gzhandler");
採用輸出緩衝控制代碼的方法確實非常有效,而且不會給伺服器帶來什麼特殊的負荷。但必須注意的是,Netscape Communicator對壓縮圖形的支援不佳,因此除非你能夠保證所有使用者都使用IE瀏覽器,否則你應該禁止壓縮JPEG和GIF圖形。一般地,對於所有其他檔案,這種壓縮都有效,但建議你針對各種瀏覽器都分別進行測試,特別是當你使用了特殊的外掛程式或者資料檢視器時這一點尤其重要。
注意事項:
1、一些Web伺服器的output_buffering預設是4069字元或者更大,即輸出內容必須達到4069字元伺服器才會flush重新整理輸出緩衝,為了確保flush有效,最好在ob_flush()函數前有以下語句:
複製代碼 代碼如下:print str_repeat("", 4096); //以確保到達output_buffering值
2、ob_* 系列函數是操作PHP本身的輸出緩衝區,所以ob_flush只重新整理PHP自身的緩衝區,而flush是重新整理apache的緩衝區。所以,正確使用倆者的順序是:先ob_flush,然後flush。ob_flush是把資料從PHP的緩衝中釋放出來,flush是把緩衝內/外的資料全部發送到瀏覽器。
3、不要誤認為用了ob_start()後,指令碼的echo/print等輸出就永遠不會顯示在瀏覽器上了。因為PHP指令碼運行結束後,會自動重新整理緩衝區並輸出內容。
http://www.bkjia.com/PHPjc/740209.htmlwww.bkjia.comtruehttp://www.bkjia.com/PHPjc/740209.htmlTechArticleob的基本原則:如果ob緩衝開啟,則echo的資料首先放在ob緩衝。如果是header資訊,直接放在程式緩衝。當頁面執行到最後,會把ob緩衝的資料...