web-dev-qa-db-fra.com

PHPUnit - getallheaders ne fonctionne pas

Je teste mon code et j'ai un problème avec l'en-tête. Dans chaque api que j'utilise 

$headers = getallheaders();

pour obtenir cela, et cela fonctionne bien lorsque je teste avec l'application ou l'extension de posth de crhome . Quand je lance mon test, comme ça

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

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

où j'essaie de tirer une carte avec ce qrcode avec un utilisateur avec ce jeton de test (pas le jeton que je vais utiliser dans l'application), je vois un appel comme celui-ci ici: https://stackoverflow.com/a/ 11681422/5475228 . Le test échoue de la manière suivante:

Erreur irrécupérable PHP: appel de la fonction non définie AppBackendBundle\Controller\getallheaders () dans /var/www/pitstop/src/AppBackendBundle/Controller/ApiController.php à la ligne 42

11
NicolaPez

de this article: 

Si vous utilisez Nginx, PHP-FPM ou toute autre méthode FastCGI d’exécution de PHP vous avez probablement remarqué que la fonction getallheaders() ne le fait pas exister. Il existe de nombreuses solutions de contournement créatives à l'état sauvage, mais PHP propose deux caractéristiques très agréables pour soulager votre douleur.

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;
    }
}
23
Matteo

je résous de cette façon (merci à https://stackoverflow.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);
}

de sorte que la requête normale de l'application obtienne un en-tête avec getallheaders (), la requête de PHPUnit le récupère depuis l'objet Request. Je ne sais pas pourquoi (si quelqu'un peut expliquer) mais ça marche.

2
NicolaPez

Une légère variation du code @Matteos qui supprime Mod-Rewrite et ajoute dans Content-Length et Content-Type qui sont normalement renvoyés par getallheaders(). Il est intéressant de noter que le cas des clés de tableau renvoyées par getallheaders() semble être omniprésent et non cohérent alors que, de toute évidence, cette version assure la cohérence.

$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;
    }
}
0
adrian