[PHP] 利用 flush()、ob_flush() 強制輸出網頁內容

正常情況下,執行中的 PHP 過程中輸出的內容會先進到緩衝區 (output_buffer)

PHP Script 全部執行完畢後,產生的資料才會從 output_buffer 一次輸出到瀏覽器上

但是若程式要跑一段時間,想要看到執行過程中輸出的內容,可以透過 ob_flush()flush() 達成

雖然看起來名稱很像,但是做的事情不太一樣:

ob_flush():把 PHP output_buffer (假設有打開)的東西輸出,但並不是立刻輸出到終端 flush():把非 PHP output_buffer,伺服器上準備輸出的資料輸出到瀏覽器上"顯示出來"

 

寫一小段測試 code

1
2
3
4
5
6
7
8
<?php
header('Content-type: text/html; charset=utf-8');
for ($i = 0; $i < 100; $i++) {
    echo $i . '<br>';
    flush();
    ob_flush();
    usleep(20000); // 20ms
}

 

HTTP Server 設定也會影響到 function

Apache 預設值不影響,不過 Nginx 會

所以如果 HTTP Server 使用 Nginx

需要針對 PHP 類型額外做設定:

編輯 /etc/nginx/site-available/default

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
# 找到針對PHP的directive
location ~ [^/].php(/|$) {
    fastcgi_split_path_info ^(.+?.php)(/.*)$;
    if (!-f $document_root$fastcgi_script_name) {
        return 404;
    }

    include fastcgi_params;
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_pass unix:/var/run/php5-fpm.sock;
    fastcgi_read_timeout 300;

    # 加入這三行
    fastcgi_keep_conn on; # fastcgi保持連線
    proxy_buffering off; # 如果沒使用proxy的話這行可以不加
    gzip off; # 關閉gzip壓縮
}

 

值得注意的是 fastcgi_keep_conn 在 Nginx 下預設是 off 的

雖然啟用後理論上效能能得到提升 (Connection TIME_WAIT 數量會明顯下降)

不過在某些特殊情況下可能會發生異常

所以預設情況下是關閉的


Reference: Re: Why does fastcgi_keep_conn default to off?

Licensed under CC BY-NC-SA 3.0 TW
comments powered by Disqus