1. 程式人生 > 程式設計 >php 輸出緩衝 Output Control用法例項詳解

php 輸出緩衝 Output Control用法例項詳解

本文例項講述了php 輸出緩衝 Output Control用法。分享給大家供大家參考,具體如下:

關於php的輸出緩衝,首先要說明的是什麼是緩衝(buffer),比如我們通過記事本在編輯檔案的時候,並不是我們輸入了內容,系統就會立刻向磁碟中寫入資料。只有我們在儲存檔案後,系統才會向磁碟寫入資料。而之前我們輸入的內容全部儲存在了檔案緩衝區中,只有當緩衝區寫滿或者執行儲存時,資料才會寫入磁碟。

而php的輸出緩衝也一樣,當我們通過echo,print等函式輸出時,這些內容首先會儲存在output buffer中,php指令碼執行完畢或者強制執行緩衝輸出操作,內容才會在瀏覽器上顯示。

現在的php版本預設是開啟output buffer的,在php.ini

output_buffering = 4096

4096表示緩衝區的大小。

<?php
for($i = 0; $i< 10; ++$i) {
  echo $i,'<br />';
  sleep(1);
}
?>

程式碼如上,執行的效果並不是我們想要的,瀏覽器在等待了10秒後,一次性的把0-9輸出在了頁面上。

原因:預設開啟了輸出緩衝,當們echo 0;時,實際上是儲存在了ob中,然後等待1秒,繼續echo 1;直到for迴圈執行完畢,整個php指令碼執行結束,這時php會把緩衝內容一次性發送到瀏覽器。

那如何才能輸出一個數,等待1秒後,再輸出下一個數?

方法如下:

1、關閉輸出緩衝區
2、自已控制輸出緩衝

<?php
//關閉緩衝區
ob_end_clean();
for($i = 0; $i< 10; ++$i) {
  echo $i,'<br />';

  //如果不加flush,則不是一個一個輸出
  flush();
  sleep(1);
}
?>

為什麼不加flush,程式就不會一個一個輸出,php並不是直接輸出給瀏覽器的,而是伺服器,php的緩衝關了,但伺服器的緩衝還有,所以呼叫flush把輸出傳送到使用者瀏覽器。

<?php
for($i = 0; $i< 10; ++$i) {
  echo $i,'<br />';
  ob_flush();
  flush();
  sleep(1);
}
?>

這段程式碼跟上面的程式碼效果是一樣的,我們通過ob_flush重新整理php緩衝,並清空緩衝區內容(但不會關閉緩衝區)。然後呼叫flush重新整理伺服器緩衝,輸出到瀏覽器。

ob其他函式的介紹:

<?php
ob_start();
for($i = 0; $i< 10; ++$i) {
  echo $i,'<br />';
}
$str = ob_get_contents();
file_put_contents('./output.txt',$str);
ob_end_clean();
//注意,這裡的ob_end_clean()只是關閉了ob_start()開啟的緩衝
for($i = 0; $i< 10; ++$i) {
  echo $i,'<br />';
  flush();
  sleep(1);
}
?>

請看上述程式碼:我們ob_start()開啟一個緩衝,for迴圈輸出的內容全部放在了緩衝區中,通過ob_get_contents()來獲取緩衝區的內容(只是得到緩衝區內容,緩衝區中的內容還存在)。然後ob_end_clean()清空並關閉緩衝。但下面的for迴圈輸出並沒有像我們想的那樣一個一個輸出。因為php允許存在多個緩衝區,我們這裡有兩個緩衝區,一個是php已經開啟的,一個是我們自已呼叫ob_start()開啟的。

<?php
ob_start();
for($i = 0; $i< 10; ++$i) {
  echo $i,$str);
ob_end_clean();
ob_end_clean();
for($i = 0; $i< 10; ++$i) {
  echo $i,'<br />';
  flush();
  sleep(1);
}
?>

修改成這樣,輸出結果就是我們想要的了。

<?php
ob_start();
var_dump(ob_get_level());

ob_start();
var_dump(ob_get_level());

ob_end_flush();
ob_end_flush();
?>

我們通過ob_get_level()獲取緩衝區的巢狀級別,分別輸出int(2) int(3),ob_end_flush()送出緩衝區內容並關閉緩衝。

<?php
echo '111';
echo '222';
ob_clean();
echo '333';
?>

ob_clean()會清空緩衝區,但不會關閉緩衝區。而ob_end_clean()會清空並且關閉。

<?php
ob_start();
echo '111';
echo '222';
$str = ob_get_clean();
echo $str;
echo '333';
$str = ob_get_flush();
file_put_contents('str.txt',$str);

for($i = 0; $i < 10; ++$i) {
  echo $i,'<br />';
  flush();
  sleep(1);
}
?>

程式碼如下,ob_start()開啟一個緩衝,輸出111和222,放入緩衝,然後ob_get_clean()獲取緩衝內容,並半閉緩衝,返回資料。這時php已開啟的緩衝並沒有關閉,然後我們把返回的資料輸出,再輸出333,通過ob_get_flush()送出緩衝內容,返回資料,並關閉緩衝(這時php的緩衝也關了),後面的for迴圈輸出也會一個一個輸出。

更多關於PHP相關內容感興趣的讀者可檢視本站專題:《php快取技術總結》、《php面向物件程式設計入門教程》、《PHP基本語法入門教程》、《PHP陣列(Array)操作技巧大全》、《php字串(string)用法總結》、《php+mysql資料庫操作入門教程》及《php常見資料庫操作技巧彙總》

希望本文所述對大家PHP程式設計有所幫助。