PHP緩衝區是預設開啟的,它的預設參數在php.ini設定檔中,值是4096位元組。在其中找到output_buffering配置參數來修改PHP緩衝區的大小。
開發者也可以在腳本中透過ob_start()
函數手動處理PHP緩衝區機制。這樣即便輸出內容超過了配置參數的大小,也不會把資料傳送給瀏覽器,ob_start()
將PHP緩衝區空間設定到足夠大,只有腳本執行結束後或呼叫 ob_end_flush()
函數,才會把資料傳送給瀏覽器。
我們編輯php.ini設定文件,對output_buffering
值進行修改並做以下測試。當output_buffering
修改為4096時,輸出較少數據,讓它小於一個PHP緩衝區。程式碼如下:
for ($i = 0; $i< 10; $i++) { echo $i . '<br/>'; sleep($i + 1); //}
執行後你會發現,它不會像常規邏輯每隔幾秒鐘就有輸出,而是直到腳本循環結束後,才會一次輸出。這種情況在腳本處理結束之前,瀏覽器介面會一直保持空白,這是由於資料量太小,輸出緩衝區沒有寫滿。寫入資料的順序:echo語句輸出到PHP緩衝區、TCP緩衝區、瀏覽器。
接下來我們再修改output_buffering=0,仍輸出較少數據,但實際數據已經大於PHP緩衝區。程式碼如下:
for ($i = 0; $i< 10; $i++) { echo $i . '<br/>'; flush(); //通知操作系统底层,尽快把数据发给客户端浏览器 sleep($i + 1); //}
此腳本的結果與剛才一定不一致,因為將緩衝區的容量設為0,也就是停用PHP緩衝區機制。 這時我們會在瀏覽器看到斷斷續續的間斷性輸出,而不必等到腳本執行完畢才看到輸出。這是因為,資料沒有在輸出快取中停留。寫資料的順序依序是echo輸出到TCP緩衝區,再輸出給瀏覽器。 我們再把參數修改為output_buffering=4096,輸出資料大於一個緩衝區。此例中不呼叫ob_start()函數。 準備一個4KB大小的檔案或使用dd指令在shell下建立一個檔案:
$dd if=/dev/zero of=f4096 bs=4096 count=1
使用以下程式碼進行驗證:
for ($i = 0; $i< 10; $i++) { echo file_get_contents('./f4096') . $i . '<br/>'; sleep($i +1); }
可以看到,程式回應還沒結束(HTTP連線並未關閉),就可以看到間斷性輸出,瀏覽器介面不會一直保持空白。儘管啟用了PHP輸出緩衝區機制,但依然會間斷性輸出,而不是一次性輸出,這是因為PHP緩衝區空間不夠用,每寫滿一個緩衝區,資料就會傳送到客戶端瀏覽器。
和上例參數一樣,即output_buffering=4096
,輸出資料大於一個PHP緩衝區。這次我們呼叫ob_start()
,程式碼如下:
ob_start(); //开启PHP缓冲区 for ($i = 0; $i< 10; $i++) { echo file_get_contents('./f4096') . $i . '<br/>'; sleep($i + 1); } ob_end_flush();
等到服務端腳本全部處理完,回應結束才會看到完整的輸出。輸出間隔時間很短,以至於感受不到停頓。在輸出之前,瀏覽器一直會保持空白,等待伺服器端資料。這是因為,PHP一旦呼叫了ob_start()
函數,就會將PHP緩衝區擴展到足夠大,直到ob_end_flush
函數呼叫或腳本運行結束才發送PHP緩衝區中的數據到客戶端瀏覽器。
ob_start
啟動output_buffering
機制。一旦激活,腳本不再直接輸出給瀏覽器,而是先暫時寫入PHP緩衝區。 PHP預設開啟output_buffering
機制,透過呼叫ob_start()
函數把output_buffering
值擴展到夠大。也可以透過$chunk_size
來指定output_buffering
的值。 $chunk_size
預設值是0,表示直到腳本執行結束後,PHP緩衝區中的資料才會傳送到瀏覽器。若設定了$chunk_size
的大小,表示只要緩衝區中資料長度達到了該值,就會將緩衝區中的資料傳送到瀏覽器。
可以透過指定$ouput_callback
參數來處理PHP緩衝區中的數據,例如函數ob_gzhandler()
,將緩衝區中的資料壓縮後再傳送給瀏覽器。
ob_get_contents()
函數是取得一份PHP緩衝區中的資料拷貝,這是一個重要的函數。請看以下範例:
<?phpob_start(); ?> <html> <body>today is <?php echo date('Y-m-d h:i:s'); ?> </body> </html> <?php $output = ob_get_contents(); ob_end_flush();echo '<! output>'.$output;?>
以上腳本執行後,檢視原始程式碼,會出現兩段相同的HTML,後者就是透過ob_get_contents()
函數取得緩衝區裡的內容。
ob_end_flush()
與ob_end_clean()
這兩個函數都會關閉輸出緩衝。
不同的是,ob_end_flush()
只是把PHP緩衝區中的資料傳送到客戶端瀏覽器,而ob_clean_clean()
將PHP緩衝區中的資料刪除,但不發送給客戶端。
ob_end_flush()
呼叫之後,PHP緩衝區中的資料依然存在,ob_get_contents()
仍可取得PHP緩衝區中的資料拷貝。
以上是php中緩衝區的範例詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!