PHP有輸出時,能夠用輸出控制函數來控制輸出php
ob_start(),將內部緩衝區(buffer)打開。當PHP遇到echo,printf等輸出語句時, PHP就會將要輸出的數據放入緩衝區(buffer)中,等待輸出。而只有當緩衝區滿了或者php運行完畢,纔將數據輸出去。輸出字節離開PHP緩衝區進去Apache緩衝區或者Nginx緩衝區(fast-cgi),以後進入瀏覽器緩衝區。以下所示:html
echo,print -> php buffer -> web server buffer(apache緩衝區,fast-cgi緩衝區) -> browser buffergit
下面這些函數的行爲受php.ini中的設置影響。github
1.output_bufferingweb
設置爲 On 時,打開內部緩衝區(buffer)apache
設置爲 Off 時,關閉內部緩衝區(buffer)瀏覽器
設置爲數字時, 限制輸出緩衝區的最大值緩存
在php.ini裏,output_buffering=4096
是默認開啓的。而此時使用ini_set()去改變output_buffering的值, 沒法生效。由於輸出緩衝區層在php程序啓動的時候,就已經打開了。因此只能經過編輯php.ini改變其初始值或者是在執行PHP程序的時候使用-d選項才能改變它們的值。cookie
2.output_handler函數
默認爲NULL
是一個回調函數,將腳本的全部輸出,用所定義的函數進行處理。相似與ob_start($output_callback)。
$output_callback:
ob_gzhandler : 使用ext/zlib壓縮輸出
mb_output_handler : 使用ext/mbstring轉換字符編碼
ob_iconv_handler : 使用ext/iconv轉換字符編碼
ob_tidyhandler : 使用ext/tidy整理輸出的HTML文本
ob_[inflate/deflate]_handler : 使用ext/http壓縮輸出
ob_etaghandler : 使用ext/http自動生成HTTP的Etag
3.implicit_flush
設置爲 On 時,打開絕對刷送。
PHP緩衝區層發送數據到web server buffer,Apache自動刷新輸出緩衝區,不須要等待刷新指令,直接就把輸出返回到browser buffer
設置爲 Off 時,關閉絕對刷送。
不自動刷新apache緩衝區,接受到數據後,等待刷新指令
在php.ini裏,implicit_flush=Off
是默認關閉的。若是想要刷新Apache緩衝區,使用PHP的flush()函數手動刷新。或者調用ob_implicit_flush()(隱式刷送)函數。
使用的時候咱們常常一塊兒使用
if (ob_get_level() == 0) ob_start(); for ($i = 0; $i<10; $i++){ echo "<br> Line to show."; echo str_pad('',4096)."\n"; ob_flush(); flush(); sleep(2); } echo "Done."; ob_end_flush();
可是ob_*系列的函數是操做php buffer,而flush則是操做web server buffer(活着特指上面所提到的Apache緩衝區)。
1.首先確定是提升性能,減小響應次數
2.修改http頭信息
咱們輸出消息到頁面表示請求和響應已經完成了,是不能再發送http頭信息了。可是使用緩衝區就不同了
ob_start(); echo "Hello\n"; setcookie("cookiename", "cookiedata"); ob_end_flush();
在上面的例子中,echo函數的輸出將一直被保存在輸出緩衝區中直到調用 ob_end_flush() 。同時,對setcookie()的調用也成功存儲了一個cookie,而不會引發錯誤。
3.避免內存限制
對於大文件來講, 開啓PHP緩衝區, 一段一段的讀取數據到瀏覽器,避免用戶等待,也避免一次讀取數據讀取耗盡內存。
4.靜態文件緩存
使用緩衝區生成靜態html文件
ob_start('ob_gzhandler'); $content = ob_get_contents(); // 打開文件 $file = fopen('./index.html', 'w'); // 將緩衝區中的內容寫入文件 fwrite($file, $content); fclose($file); ob_end_clean();
5.處理輸出的內容
eg:進行gzip壓縮,進行簡繁轉換,或者進行一些字符串替換
tips:不要在輸出緩衝區回調函數內調用任何緩衝區相關的函數,也不要在回調函數中輸出任何東西。是由於有些PHP的內部函數也使用了輸出緩衝區,它們會疊加到其餘的緩衝區上,這些函數會填滿本身的緩衝區而後刷新,或者是返回裏面的內容。eg:print_r()、highlight_file()和highlight_file::handle()等。在輸出緩衝區的回調函數中使用這些函數,會致使未定義的錯誤。
[ 1 ] : 深刻理解php的輸出緩衝區(output buffer)