ob,輸出緩衝區,是output buffering的簡稱,而不是output cache。ob用對了,是能對速度有必定的幫助,可是盲目的加上ob函數,只會增長CPU額外的負擔。php
下面我說說ob的基本做用:
1)防止在瀏覽器有輸出以後再使用setcookie()、header()或session_start()等發送頭文件的函數形成的錯誤。其實這樣的用法少用爲好,養成良好的代碼習慣。
2)捕捉對一些不可獲取的函數的輸出,好比phpinfo()會輸出一大堆的HTML,可是咱們沒法用一個變量例如$info=phpinfo();來捕捉,這時候ob就管用了。
3)對輸出的內容進行處理,例如進行gzip壓縮,例如進行簡繁轉換,例如進行一些字符串替換。
4)生成靜態文件,其實就是捕捉整頁的輸出,而後存成文件。常常在生成HTML,或者整頁緩存中使用。html
對於剛纔說的第三點中的GZIP壓縮,多是不少人想用,卻沒有真用上的,其實稍稍修改下代碼,就能夠實現頁面的gzip壓縮。數據庫
ob_start(ob_gzhandler); 內容
沒錯,加一個ob_gzhandler這個回調函數就能夠了,不過這麼作有些小問題,一是須要zlib支持,二是沒有判斷瀏覽器是否支持gzip(如今好像都支持,iphone瀏覽器好像都支持了)。
之前的作法是判斷一下瀏覽器是否支持gzip,而後用第三方的gzip函數來壓縮ob_get_contents() 的內容,最後echo。
apache
1、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。
2、實例講解緩存
一、使 header() 函數前能夠有echo代碼服務器
Output Control 函數可讓你自由控制腳本中數據的輸出。它很是地有用,特別是對於:當你想在數據已經輸出後,再輸出文件頭的狀況。
輸出控制函數不對使用 header() 或 setcookie(),發送的文件頭信息產生影響,只對那些相似於 echo() 和 PHP 代碼的數據塊有做用。 cookie
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纔會輸出,因此並不會有任何文件頭輸出的錯誤!
二、保存 phpinfo() 函數的輸出session
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
三、靜態模版技術iphone
所謂靜態模版技術就是經過某種方式,使得用戶在client端獲得的是由PHP產生的html頁面。若是這個html頁面不會再被更新,那麼當另外的用戶再次瀏覽此頁面時,程序將不會再調用PHP以及相關的數據庫,對於某些信息量比較大的網站,例如sina、16三、sohu。相似這種的技術帶來的好處是很是巨大的。
ob_start(); //打開緩衝區 php頁面的所有輸出 $content = ob_get_contents(); //取得php頁面輸出的所有內容 $fp = fopen("output00001.html", "w"); //建立一個文件,並打開,準備寫入 fwrite($fp, $content); //把php頁面的內容所有寫入output00001.html,而後…… fclose($fp);
3、輸出緩存句柄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圖形。通常地,對於全部其餘文件,這種壓縮都有效,但建議你針對各類瀏覽器都分別進行測試,特別是當你使用了特殊的插件或者數據查看器時這一點尤爲重要。
注意事項:
一、一些Web服務器的output_buffering默認是4069字符或者更大,即輸出內容必須達到4069字符服務器纔會flush刷新輸出緩衝,爲了確保flush有效,最好在ob_flush()函數前有如下語句:
print str_repeat("", 4096); //以確保到達output_buffering值
二、ob_* 系列函數是操做PHP自己的輸出緩衝區,因此ob_flush只刷新PHP自身的緩衝區,而flush是刷新apache的緩衝區。因此,正確使用倆者的順序是:先ob_flush,而後flush。ob_flush是把數據從PHP的緩衝中釋放出來,flush是把緩衝內/外的數據所有發送到瀏覽器。
三、不要誤認爲用了ob_start()後,腳本的echo/print等輸出就永遠不會顯示在瀏覽器上了。由於PHP腳本運行結束後,會自動刷新緩衝區並輸出內容。
轉載:http://sunlufu2009.blog.163.com/blog/static/149068329201104101826264/