简体   繁体   中英

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

headers_sent will tell me when output was sent to the browser. However, it can be that no body was sent, eg 302 redirect.

How do I tell in register_shutdown_function context what content has been sent to the browser, or at least what was Content-Length .

The content lenght header will no being set by apache if it is a PHP script. This is because the webserver can't know about this as the content is dynamically created. However the headers have to sent before the body. So the only way to get the length of the content is to generate it, obtain it's length, send the header and then send the content.

In PHP you can use ob_* set of functions (output buffering) to achieve this. Like this:

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();
});

Warning This will be unreliable if you are using gzip encoded transfer. There has been posted a workaround on the PHP web site ,

Also you might need to know that output buffers can be nested in PHP. If there is another ob_start() call in my example above than you'll end up seeing nothing in the browser because just the inner buffer gets flushed (into the outer one)

The following example takes care on this. In order to ease the process it just overwrites the header multiple times, which shouldn't be a performance issue as header() is basically a simple string operation. PHP sends the headers only before some output or at the end of the script.

Here comes the code which has been tested gzip safe and works reliable with nested unclosed buffers:

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();
    }
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM