PHPUnit - getallheaders 不起作用

Posted

技术标签:

【中文标题】PHPUnit - getallheaders 不起作用【英文标题】:PHPUnit - getallheaders not work 【发布时间】:2017-05-16 14:12:19 【问题描述】:

我正在测试我的代码,但标题有问题。在我使用的每个 api 中

$headers = getallheaders();

要做到这一点,当我使用应用程序或 crhome 邮递员扩展程序进行测试时,这可以正常工作。 当我启动我的测试时,像这样

 $client = $this->createClient();
    $client->request('GET', '/api/shotcard',
        ['qrcode'=>'D0m1c173'], [],
        ['HTTP_API_TOKEN' => 'abc123']
    );

    $this->assertEquals(200, $client->getResponse()->getStatusCode());

我尝试使用该 qrcode 与具有该测试令牌(不是我将在应用程序中使用的令牌)的用户一起拍摄一张卡片,我在这里看到这样的调用:https://***.com/a/11681422/5475228。 测试以这种方式失败:

php 致命错误:在第 42 行的 /var/www/pitstop/src/AppBackendBundle/Controller/ApiController.php 中调用未定义函数 AppBackendBundle\Controller\getallheaders()

【问题讨论】:

来自文档:此函数是 apache_request_headers() 的别名。请阅读 apache_request_headers() 文档以获取有关此函数如何工作的更多信息。 php.net/manual/en/function.apache-request-headers.php 您使用的是哪个版本的php?自 PHP 5.5.7 起,它应该可以从 CLI 获得 【参考方案1】:

来自this文章:

如果您使用 nginx、PHP-FPM 或任何其他运行 PHP 的 FastCGI 方法 你可能已经注意到函数getallheaders() 没有 存在。野外有许多创造性的解决方法,但 PHP 提供 两个非常好的功能可以减轻您的痛苦。

来自用户在getallheaders()joyview at gmail dot comjoyview at gmail dot com 的 PHP 手册函数中贡献的 cmets

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

【讨论】:

我也使用这个解决方案,当我从应用程序或邮递员测试时工作正常。但是 PHPUnit 不使用,我也尝试打印标题,PHPUnit 打印一个空值。我正在使用 php 5.5.9 不幸的是,这只能识别以HTTP_ 为前缀的标头。此实现不会检索 AcceptUser-Agent 等标头以及任何自定义 HTTP 标头。 是的@OndřejBouda,但你可以实现添加else 声明的行为我想 @Matteo 抱歉评论有误,$_SERVER 实际上包含 AcceptUser-Agent。但是,对于自定义 HTTP 标头,可能无法通过这种方式检索这些标头。变量$_SERVER只包含几个标准的HTTP头,如documented,而getallheaders()则返回客户端发送的所有头。 嗨@OndřejBouda HTTP_ 技巧是关于BrowserKit 实现的,如here 所述示例:headers are also part of $_SERVER, by prefixing them with HTTP_【参考方案2】:

我就是这样解决的(感谢https://***.com/a/11681422/5475228)

private function request_headers($type, Request $request)

    if(function_exists("getallheaders"))
    
        if($header = getallheaders()[$type])
        
            return $header;
        
    

    return $request->headers->get($type);

所以来自app的正常请求使用getallheaders()获取header,来自PHPUnit的请求从Request对象中获取。我不知道为什么(如果有人可以解释的话)但是有效。

【讨论】:

【参考方案3】:

与@Matteos 代码略有不同,它删除了 Mod-Rewrite 并添加了通常由 getallheaders() 返回的 Content-Length 和 Content-Type。有趣的是,getallheaders() 返回的数组键的情况似乎无处不在,而且不一致,而显然这个版本确保了一致性。

$allHeaders = array();
foreach($_SERVER as $name => $value) 
    if($name != 'HTTP_MOD_REWRITE' && (substr($name, 0, 5) == 'HTTP_' || $name == 'CONTENT_LENGTH' || $name == 'CONTENT_TYPE')) 
        $name = str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', str_replace('HTTP_', '', $name)))));
        $allHeaders[$name] = $value;
    

【讨论】:

以上是关于PHPUnit - getallheaders 不起作用的主要内容,如果未能解决你的问题,请参考以下文章

PHP getallheaders 替代

MimeMessage.getAllHeaders() 在两个不同的项目中返回两个不同的类

`xhr.getAllHeaders()` 在浏览器扩展上下文中缺少一些标题?

PHP接收http请求头信息

php PHPでgetallheaders()が动かない时用の关数https://stackoverflow.com/questions/13224615/get-the-http-headers-f

Symfony:如何正确地从phpunit / phpunit切换到phpunit桥