PHP headers_list() is not showing all headers

末鹿安然 提交于 2019-12-04 04:36:41

问题


According to the documentation: http://php.net/manual/en/function.headers-list.php, and this comment: http://php.net/manual/en/function.headers-list.php#110330, php code:

<?php var_dump(header_list()); ?>

Does not show the status headers.


This strange behavior is strange. So there are two questions:

  1. Why? (I'm not sure if this question is opinion based, if it is, and there is no REAL explanation please omit it. I mean that sometimes opinion based questions aren't opinion based, and really have explanation, and this cannot be predict before they are asked).
  2. I know that I can use my own function to set header, which will set header and additionally remember that this header was set. But this is kind of... workaround, as header_list() is quite sure HERE, FOR THAT. Additionally those headers are somewhere in the php engine memory so saving them second time inside script is not memory efficient. So... What is the back-door to get all headers, not as stupid as workaround below? This can be useful for example as a part of debug / developer class that is rendering all the "developer" data as html comments at the end of the page. Of course I'm omitting the content length header which is too soon to predict.
  3. It looks like this function omit all the headers that don't have colon... Is it right?

To post more code, simple workaround to header function (linear not object, using globals and not static class just to show the idea). With the assumption that header function is omitting headers without colons (which may not be quite true...):

<?php
    // Mechanism:
    $headers = array();
    function setHeader($header) {
        header($header);
        if (strpos($header, ':') === false) {
            global $headers;
            $headers[] = $header;
        }
    }
    function getHeaders() {
        global $headers;
        return array_merge($headers, header_list());
    }

    // Example:
    setHeader('HTTP/1.1 404 Not Found');
    var_dump(getHeaders());
?>

回答1:


Checking the engine source for headers_list and http_response_code, notice that the value for general headers and status code are separated:

// headers_list
SG(sapi_headers).headers

// http_response_code
SG(sapi_headers).http_response_code

But HTTP response code isn't the only header with dedicated storage: Content-Type does, too:

SG(sapi_headers).mimetype = NULL;

So what's going on here? The complete header() algorithm specifically checks for the following strings to adjust state:

  • HTTP/
  • Content-Type
  • Content-Length
  • Location
  • WWW-Authenticate

HTTP/ is checked specifically because that's how one set the status code explicitly before PHP 5.4: after that, http_response_code is available and is recommended for clarity. That header() was used is confusing, for the reason you're asking in this question and on general principle: the http header BNF clearly doesn't include status line:

header-field   = field-name ":" OWS field-value OWS

PHP handles the others separately because they are single-value headers and/or their value matters for efficiency in later calculations.

TL;DR: HTTP/ set by header() isn't included in headers_list() because HTTP/ status lines are not headers in the strict RFC sense. But for the PHP < 5.4 limitation that header() was the only way to set HTTP/ status, it'd likely have never been a confusing issue.




回答2:


It seems that only the status code is missing from the header_list.

You can get the current status code (they probably overwrite one another) using another function: http_response_code.



来源:https://stackoverflow.com/questions/31555392/php-headers-list-is-not-showing-all-headers

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!