簡體   English   中英

如何在請求結束時獲得Content-Length?

[英]How to get Content-Length at the end of request?

headers_sent會告訴我何時將輸出發送到瀏覽器。 但是,可能是沒有正文被發送,例如302重定向。

我如何在register_shutdown_function上下文中知道已將什么內容發送到瀏覽器,或者至少是什么Content-Length

如果內容長度標頭是PHP腳本,則不會由apache設置。 這是因為在動態創建內容時,Web服務器無法得知。 但是,標頭必須在正文之前發送。 因此,獲取內容長度的唯一方法是生成內容,獲取內容長度,發送標頭然后發送內容。

在PHP中,可以使用ob_*函數集(輸出緩沖)來實現此目的。 像這樣:

ob_start();

echo 'hello world'; // all your application's code comes here

register_shutdown_function(function() {
    header('Content-Length: ' . ob_get_length());
    ob_end_flush();
});

警告如果您使用的是gzip編碼的傳輸方式,這將是不可靠的。 已經在PHP網站上發布了解決方法

另外,您可能需要知道輸出緩沖區可以嵌套在PHP中。 如果在上面的示例中還有另一個ob_start()調用,那么您最終將不會在瀏覽器中看到任何內容,因為僅刷新了內部緩沖區(進入了外部緩沖區)

以下示例對此有所注意。 為了簡化此過程,它只是多次重寫標頭,這不應該是性能問題,因為header()基本上是一個簡單的字符串操作。 PHP僅在某些輸出之前或在腳本末尾發送標頭。

這是經過gzip安全測試的代碼,可與嵌套未封閉的緩沖區可靠地工作:

ob_start('ob_gzhandler');

echo 'hello world';

// another ob_start call. The programmer missed to close it.
ob_start();

register_shutdown_function(function() {
    // loop through buffers and flush them. After the operation the
    // Content-Lenght header will contain the total of them all
    while(ob_get_level()) {
        header('Content-Length: ' . ob_get_length(), TRUE);
        ob_end_flush();
    }
});

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM