首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

深入理解 PHP 輸出緩衝機制與相關函數

     編輯:PHP 相關知識

PHP 輸出緩衝的運作原理

在 PHP 中,當我們使用 echo 或 print 輸出內容時,數據並不會立即經由 TCP 傳送給瀏覽器顯示,而是先寫入 PHP 內部的輸出緩衝區。這機制在 TCP 緩衝之前建立了一個新的隊列,數據必須依次通過:echo/print → PHP buffer → TCP buffer → 瀏覽器。只有當 PHP 緩衝區寫滿、腳本結束或主動刷新時,數據才會被系統內核交給 TCP 發送給客戶端。

核心刷新函數詳解

1. flush()

flush() 用於刷新 PHP 程序的輸出緩衝,將截至目前的所有輸出發送到用戶瀏覽器。但它不影響服務器或客戶端瀏覽器的緩存模式,也不會改變 PHP 本身的緩存行為。

2. ob_flush()

ob_flush() 專門針對 PHP 自身的輸出緩衝(由 php.ini 中的 output_buffering 控制)。它將輸出緩衝區的內容取出並設置為「等待輸出」狀態,但不會直接發送到客戶端。因此,通常需要先呼叫 ob_flush() 再呼叫 flush(),客戶端才能即時獲得腳本輸出。

3. ob_implicit_flush()

啟用 ob_implicit_flush(true) 後,每當有輸出動作(如 echo)就會立即把輸出發送到瀏覽器,省去每次手動呼叫 flush() 的麻煩。

關鍵 php.ini 設定參數

  • output_buffering:On/Off 或整數(如 4096)。開啟時所有腳本啟用輸出緩衝控制;設為整數時,緩衝區達到該位元組數會自動刷新。關閉時 echo 即時發送;開啟時內容會緩存至腳本結束才一次發送。
  • implicit_flush:On/Off。設為 On 相當於每次 echo 後自動加上 flush()。

實戰範例:實現逐秒輸出數字

<?php
// 寫法一:手動雙重刷新
ob_end_clean();
echo str_pad(" ", 256); // IE 需 256 字節才開始顯示
for ($i = 100; $i > 0; $i--) {
    echo $i, '<br/>';
    ob_flush();
    flush();
    sleep(1);
}
?>
<?php
// 寫法二:隱式刷新
ob_implicit_flush(true);
echo str_pad(" ", 256);
for ($i = 100; $i > 0; $i--) {
    echo $i, '<br/>';
    ob_flush(); // 僅需 ob_flush
    sleep(1);
}
?>

注意:str_pad(" ", 256) 是為了滿足 IE 瀏覽器需接收 256 字節才開始渲染的特性。

其他影響輸出的因素

  • Web 伺服器(特別是 Windows 下的 Apache、mod_gzip 等模組)可能自行緩存輸出,導致 flush() 不立即生效。
  • 瀏覽器端也會緩存:Netscape 等待換行或 HTML 標籤開頭;IE 需 256 字節才顯示頁面。

自訂緩存類範例

以下示範一個簡單的檔案緩存類,利用 ob_start() 捕獲輸出並寫入靜態檔案:

<?php
class my_cache {
    private $cache_time, $cache_file;
    public function __construct($cache_file='index.html', $cache_time=1) {
        $this->cache_file = $cache_file;
        $this->cache_time = $cache_time;
    }
    public function cache_start() {
        if ($this->cache_active()) {
            include $this->cache_file;
            exit;
        }
        ob_start();
    }
    private function cache_active() {
        if (file_exists($this->cache_file)) {
            $last_time = @filemtime($this->cache_file);
            if ($this->cache_time < $last_time) return true;
            unlink($this->cache_file);
        }
        return false;
    }
    private function cache_creat() {
        $dirs = explode('/', $this->cache_file);
        $path = '';
        for ($i=0; $i<count($dirs)-1; $i++) {
            $path .= $dirs[$i].'/';
            if (!file_exists($path)) mkdir($path);
        }
    }
    public function cache_end() {
        $content = ob_get_contents();
        $this->cache_creat();
        $fp = @fopen($this->cache_file, 'w+');
        fwrite($fp, $content);
        ob_end_flush();
    }
    public function cache_clean() {
        return @unlink($this->cache_file);
    }
}
?>

使用方式:

<?php
include 'cache_my_class.php';
$my_cache = new my_cache('./chunge/ge/hao/index.html', 5);
$my_cache->cache_start();
echo '我愛吃橘子香蕉!<br>';
$my_cache->cache_end();
?>
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved