在PHP中获取当前请求的HTTP头

46

使用PHP获取当前请求的http头部是否可能? 我没有使用Apache作为Web服务器,而是使用nginx。

我尝试使用getallheaders()方法,但我收到了Call to undefined function getallheaders()的错误信息。


正如你在我的回答中所看到的,你仍然可以使用getallheaders()函数。 - gabrielem
请在此处投票:https://bugs.php.net/bug.php?id=62596 - Bell
6个回答

50

摘自文档,有个人写了一篇评论...

if (!function_exists('getallheaders')) 
{ 
    function getallheaders() 
    { 
       $headers = array (); 
       foreach ($_SERVER as $name => $value) 
       { 
           if (substr($name, 0, 5) == 'HTTP_') 
           { 
               $headers[str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', substr($name, 5)))))] = $value; 
           } 
       } 
       return $headers; 
    } 
} 

1
谢谢,它运行正常。但你能解释一下在该函数中 ucwordsstrtolower 的目的是什么吗?它们是否必要? - Michal S.
2
这个函数的一个bug是大写的头部信息,比如“DNT”(不跟踪)会变成“Dnt”,这与本地的getallheaders()函数不同。 - Bell
3
这个功能中没有出现“授权”(Authorization)… 有任何想法? - Toto NaBendo

27

改进了@Layke的函数,使其更加安全易用:

if (!function_exists('getallheaders'))  {
    function getallheaders()
    {
        if (!is_array($_SERVER)) {
            return array();
        }

        $headers = array();
        foreach ($_SERVER as $name => $value) {
            if (substr($name, 0, 5) == 'HTTP_') {
                $headers[str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', substr($name, 5)))))] = $value;
            }
        }
        return $headers;
    }
}

我希望我能够将这个作为对他答案的评论,但是还在努力提高声望 -- 这是我最初的回复之一。


4

这个问题最终在PHP 7.3.0中得到解决,请查看发布说明

修复了#62596号bug(使用PHP-FPM时,getallheaders()函数不可用)。


你能详细说明这是什么意思吗?(答案应该是自包含的,例如“鼓励链接到外部资源,但请添加链接周围的上下文,以便您的同行用户了解它是什么以及为什么存在。始终引用重要链接的最相关部分”https://stackoverflow.com/help/how-to-answer) - Sybille Peters
此外,链接经常在一段时间后失效... - Sybille Peters

3

将getallheaders()和apache_request_headers()结合在一起用于nginx

    function get_nginx_headers($function_name='getallheaders'){

        $all_headers=array();

        if(function_exists($function_name)){ 

            $all_headers=$function_name();
        }
        else{

            foreach($_SERVER as $name => $value){

                if(substr($name,0,5)=='HTTP_'){

                    $name=substr($name,5);
                    $name=str_replace('_',' ',$name);
                    $name=strtolower($name);
                    $name=ucwords($name);
                    $name=str_replace(' ', '-', $name);

                    $all_headers[$name] = $value; 
                }
                elseif($function_name=='apache_request_headers'){

                    $all_headers[$name] = $value; 
                }
            }
        }


        return $all_headers;
}

3
您可以将服务器升级到PHP 5.4,从而通过fastcgi访问getallheaders(),或者使用foreach循环和一些正则表达式从$_SERVER中解析出您需要的内容。

1
nginx 是否总是运行在 FastCGI 上?这就是为什么 getallheaders() 在 PHP 5.3 下无法工作的原因吗? - Ben Harold
1
@BenHarold 请查看 getallheaders 的更新日志: 5.4:此函数在 FastCGI 下可用。先前,仅在将 PHP 安装为 Apache 模块时才支持此函数。 - Fred Wuerges
@FredWuerges 我确实阅读了更新日志。这就是为什么我提出了这些问题。稍微改一下措辞:nginx是否总是使用FastCGI,这就是为什么在使用PHP 5.3或更早版本与nginx时getallheaders()无法工作的原因吗?这是否意味着在使用PHP 5.4和nginx时,getallheaders()apache_request_headers()都可以正常工作? - Ben Harold
4
这在nginx上仍然无效,根据PHP文档,getallheaders被归类为Apache函数,因为它只适用于Apache,这在确认了PHP 5.5和nginx后仍然如此。 - Sammaye
7
目前在 PHP7 中,在 FastCGI 模式下的 nginx 上,getallheaders 函数无法正常工作。 - Jesse Greathouse
显示剩余2条评论

0

这应该可以工作:

<?php 

print_r(
  array_intersect_key(
    $_SERVER,
    array_flip(
      preg_grep(
        '/^HTTP_/', 
        array_keys($_SERVER),
        0
      )
    )
  )
);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接