PHP 輸出快取

alansleep發表於2013-01-31

一般的PHP指令碼中,PHP標籤之外的任何HTML語句將會傳送到瀏覽器客戶端,而預設的PHP的echo,print之類的輸出將會被快取.當快取達到特定的大小或頁面指令碼執行,或強行重新整理緩衝區才會傳送到瀏覽器客戶端.

比如,下面程式碼會迴圈完後再把輸出發往瀏覽器

for($i=0; $i!=3;++$i)
{
    echo date('Y-m-d h:i:s').'<br/>';
    sleep(1);
}

php.ini的outputing_buffer欄位預設是4096,表示快取的大小,如果大於該值則會像瀏覽器客戶端輸出.該值可以修改.

但有時需求對輸出進行嚴格控制.就比如我想輸出了100k的資料,但是想一次連續的傳送到客戶端,想壓縮要傳輸的資料.php可以對輸出快取進行控制,常見的函式有:

ob_start():啟動輸出快取.

ob_get_contents():得到快取內容字串.

ob_flush():重新整理快取.

flush():重新整理快取,php重新整理快取必須是同時呼叫ob_flush和flush.除非呼叫ob_implicit_flush(true).

ob_implicit_flush(true/false):開啟關閉絕對重新整理快取方式.如果為true,則手動重新整理快取時只要呼叫ob_flush,反之除了呼叫ob_flush還要呼叫flush.

ob_clean():清空快取,不關閉快取.

ob_end_flush():重新整理快取,清空並關閉快取.

ob_end_clean():重新整理快取,清空並關閉快取.

php會在指令碼執行時自動關閉快取.所以可以不用顯示呼叫ob_end_xxx.但良好的風格不應該省略這些.而且ob_start應該是和這些ob_end_xx一一對應的.

下面的程式碼展示鎖住緩衝區一起輸出:下面的輸出將一起在web上顯示,也就是一起重新整理到瀏覽器.儘管他超過了預設設定的緩衝區大小.

<?php
ob_start();

for($i=0; $i!=10240;++$i)
{
    echo '1';
    if($i == 4096)
    {    
        echo '<br/><br/>';
        sleep(3);
    }
}

ob_end_flush();
?>

下面的程式碼是演示控制指令碼每輸出一次,就重新整理快取向瀏覽器傳送資料.

<?php
// ob_implicit_flush(true);
ob_flush();
flush();
for($i=0; $i!=3;++$i)
{
    echo date('Y-m-d h:i:s').'<br/>';
    ob_flush();
    flush();
    sleep(1);
}
?>

上面每迴圈一次就會向瀏覽器重新整理一次當前時間.瀏覽器裡的頁面會無重新整理的每隔1秒多顯示一條資料.

如果把上面註釋的ob_implicit_flush(true)啟用,則可不用書寫ob_flush()後的flush().

我的部落格

相關文章