2019年1月1日 星期二

DW_PHP_AJAX_CH4 PHP對資料的接收與輸出_(5)緩衝區的使用

通常, 在下達輸出命令時, 網頁伺服器便將資料立即送交客戶端的瀏覽器, 此時, PHP程式並不一定是已經執行完畢了, 因此, 網頁伺服器可能是一邊在執行敘述命令, 另一邊又在忙著輸出資料, 所以造成網頁伺服器的負載較重, 為了改善這種情形, 可以呼叫「ob_start()」函數, 讓要輸出到使用者端瀏覽器的資料先寫入到「buffer(緩衝區)」裡, 等到PHP程式執行完畢, 也就是整個PHP網頁都解譯完畢, 再將存放在緩衝區裡的資料一併(全部的資料)輸出到使用者端瀏覽器。 

在上一節範例的說明中, 筆者已強調header()函數只可用在尚未有任何資料輸出至瀏覽器之前才可呼叫, 否則將會產生錯誤, 因此, 可應用「ob_start()」函數, 讓整個PHP網頁都解譯完畢後, 再將存放在緩衝區裡的資料一併全部地輸出到使用者端瀏覽器:
<body>
<?php
ob_start();
header("Location: message.htm");
?>
</body>

喔喔!上例還是錯了, 因為上例的HTML標籤(<body>)放置在「ob_start();」命令敘述之前, HTML標籤已早一步執行輸出的動作了, 所以, 「ob_start();」命令敘述應該擺在任何HTML標籤或header()函數、echo()、print()函數、printf()函數命令敘述之前, 最簡單的方法就是將「ob_start();」命令敘述放在PHP程式網頁的第一行。


 [強制輸出與清除緩衝區資料] 

當執行「ob_start();」命令敘述後, 也就是開啟緩衝區後, 並不一定要等到整份PHP網頁都解譯完畢後才能開始輸出資料, 在PHP網頁解譯的過程中, 可以利用flush()函數強制將存放於緩衝區的資料立即輸出, 也可以利用ob_end_flush()函數將存放於緩衝區的資料輸出並關閉緩衝區。
<?php
ob_start();
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>使用緩衝區</title>
</head>

<body>
<?php
echo "資料第一次存入緩衝區";
ob_end_flush();

ob_start();
echo "資料第二次存入緩衝區";
ob_end_clean();
?>
</body>
</html>

以上例來說, 輸出的資料將只有被強制輸出的HTML標籤(含<body>與之前的HTML標籤)與「資料第一次存入緩衝區」, 還有整份PHP網頁都解譯完畢才開始輸出的資料「</html>、</body>」。

  1.  含<body>與之前的HTML標籤跟「資料第一次存入緩衝區」在ob_end_flush()命令執行後被強制輸出, 而緩衝區也同時被關閉了。 
  2. 當執行「echo "資料第二次存入緩衝區";」命令敘述後, 『資料第二次存入緩衝區』被存放至緩衝區。
  3.  ob_end_clean();」命令敘述執行後, 緩衝區內容被清除, 『資料第二次存入緩衝區』被人間蒸發不存在了!而緩衝區也再次被關閉了。
  4.  「</html>、</body>」並沒有被存放至緩衝區, 而是被直接輸出。 

以上論證可藉由範例flush.php執行後, 從檢視網頁原始檔中獲得證明, 如下:

沒有留言:

張貼留言