首頁  >  文章  >  後端開發  >  php中緩衝區的範例詳解

php中緩衝區的範例詳解

黄舟
黄舟原創
2017-08-10 11:27:261607瀏覽

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 . &#39;<br/>&#39;;
    sleep($i + 1);      
    //}

執行後你會發現,它不會像常規邏輯每隔幾秒鐘就有輸出,而是直到腳本循環結束後,才會一次輸出。這種情況在腳本處理結束之前,瀏覽器介面會一直保持空白,這是由於資料量太小,輸出緩衝區沒有寫滿。寫入資料的順序:echo語句輸出到PHP緩衝區、TCP緩衝區、瀏覽器。

接下來我們再修改output_buffering=0,仍輸出較少數據,但實際數據已經大於PHP緩衝區。程式碼如下:

 for ($i = 0; $i< 10; $i++) {    echo $i . &#39;<br/>&#39;;
    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(&#39;./f4096&#39;) . $i . &#39;<br/>&#39;;
    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(&#39;./f4096&#39;) . $i . &#39;<br/>&#39;;
    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(&#39;Y-m-d h:i:s&#39;);  
 ?>
</body>
</html>
<?php
$output = ob_get_contents();
ob_end_flush();echo &#39;<! output>&#39;.$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中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn