Jak získat hlavičky požadavků HTTP v jazyce PHP
Chcete číst hlavičky požadavků HTTP z kódu PHP spuštěného za webovým serverem. Tento průvodce vás seznámí s praktickými způsoby, jak toho dosáhnout: přímo prostřednictvím aplikace $_SERVER, s použitím getallheaders or apache_request_headersa prostřednictvím objektů požadavků PSR-7, které používá mnoho moderních frameworků.
Použití getallheaders a apache_request_headers
PHP také poskytuje funkce, které vracejí všechny hlavičky požadavků přímo jako asociativní pole.
getallheaders()apache_request_headers()
getallheaders je alias apache_request_headers a oba načtou všechny hlavičky HTTP požadavku z aktuálního požadavku.
Základní použití getallheaders
If getallheaders je ve vašem prostředí k dispozici, je to obvykle nejjednodušší způsob, jak zobrazit vše, co klient odeslal:
$headers = getallheaders(); foreach ($headers as $name => $value) { echo $name . ': ' . $value . PHP_EOL;}
Co to dělá:
- Hovory
getallheaders()načíst asociativní pole všech záhlaví. - Iteruje a vytiskne každou hlavičku.
- Názvy záhlaví se vracejí v normalizované podobě (např.
Accept-Language,User-Agent,Content-Type).
Kdy je to vhodné:
- Běžíte pod Apache, FastCGI nebo FPM, kde jsou tyto funkce k dispozici.
- Nechcete se zabývat
$_SERVERpojmenování ručně. - Chcete získat úplný výpis hlaviček pro ladění nebo protokolování.
V některých prostředích (například v prostém CLI nebo v PHP vytvořeném bez rozšíření souvisejícího s Apache) tyto funkce nemusí existovat a jejich volání by vyvolalo fatální chybu.
Náhradní polyfill pro getallheaders
Na serverech, kde getallheaders chybí (například u některých nastavení nginx), je běžným vzorem poskytnout kompatibilní funkci, která obnoví hlavičky z adresy. $_SERVER.
if (!function_exists('getallheaders')) { function getallheaders(): array { $headers = []; foreach ($_SERVER as $name => $value) { if (str_starts_with($name, 'HTTP_')) { $headerName = substr($name, 5); $headerName = str_replace('_', ' ', $headerName); $headerName = ucwords(strtolower($headerName)); $headerName = str_replace(' ', '-', $headerName); $headers[$headerName] = $value; } } if (isset($_SERVER['CONTENT_TYPE'])) { $headers['Content-Type'] = $_SERVER['CONTENT_TYPE']; } if (isset($_SERVER['CONTENT_LENGTH'])) { $headers['Content-Length'] = $_SERVER['CONTENT_LENGTH']; } return $headers; }} foreach (getallheaders() as $name => $value) { echo $name . ': ' . $value . PHP_EOL;}
Proč je to užitečné:
- Vaše aplikace může volat
getallheaders()bezpodmínečně. - Na hostitelích, které poskytují nativní funkci, je k dispozici vestavěná implementace.
- U hostitelů, kteří to nedělají, se i přesto zobrazí kompatibilní chování založené na.
$_SERVER.
Poznámka k Authorization:
getallheadersčasto zahrnujeAuthorizationzáhlaví, kde$_SERVERsám o sobě ne.- Pokud vám záleží na hlavičkách auth, otestujte toto chování na konkrétním serveru a nastavení PHP.
Přístup k jedné hlavičce pomocí getallheaders
V názvech hlaviček požadavků se nerozlišují velká a malá písmena, ale klíče pole vrácené funkcí getallheaders mají specifické pouzdro (například User-Agent). Abyste se vyhnuli odhadům, můžete je před vyhledáváním normalizovat.
<?php$headers = getallheaders(); // Normalize keys to lowercase for case insensitive lookup$headersLower = array_change_key_case($headers, CASE_LOWER); $userAgent = $headersLower['user-agent'] ?? null;$authHeader = $headersLower['authorization'] ?? null; echo 'User-Agent: ' . ($userAgent ?? '[none]') . PHP_EOL;echo 'Authorization: ' . ($authHeader ?? '[none]') . PHP_EOL;
Na čem záleží:
array_change_key_casevytvoří nové pole s malými klíči.- Poté můžete vyhledat libovolnou hlavičku pomocí konzistentního klíče, jako např.
'authorization'. - Tímto vzorem se předejde nenápadným chybám, když server nebo rozšíření používá mírně odlišné psaní velkých písmen v názvu hlavičky.
Čtení hlaviček požadavků z $_SERVER
PHP vystavuje hlavičky příchozích požadavků prostřednictvím příkazu $_SERVER superglobální. Pro většinu hlaviček vytváří PHP klíče, které:
- Začněte s
HTTP_ - Používejte velká písmena
- Nahrazení pomlček podtržítky
Například záhlaví:
Accept-Language: en-US,en;q=0.9
je obvykle k dispozici jako:
$_SERVER['HTTP_ACCEPT_LANGUAGE'];
Toto chování je zdokumentováno v příručce PHP, kde je vysvětleno, že hlavičky požadavků jsou mapovány na. $_SERVER položky podle tohoto vzoru pojmenování.
Čtení specifických hlaviček z $_SERVER
Minimální příklad, který čte několik běžných hlaviček a jednu vlastní:
// Common request headers$acceptLanguage = $_SERVER['HTTP_ACCEPT_LANGUAGE'] ?? null;$userAgent = $_SERVER['HTTP_USER_AGENT'] ?? null; // Custom header: X-Requested-With$requestedWith = $_SERVER['HTTP_X_REQUESTED_WITH'] ?? null; echo "Accept-Language: " . ($acceptLanguage ?? '[none]') . PHP_EOL;echo "User-Agent: " . ($userAgent ?? '[none]') . PHP_EOL;echo "X-Requested-With: " . ($requestedWith ?? '[none]') . PHP_EOL;
Co to dělá:
- Čte hodnoty z
$_SERVERpomocíHTTP_předponu a velká písmena s podtržítky. - Používá operátor koalescence null
??aby skript nevyhazoval hlášení, pokud chybí hlavička. - Vytiskne každou hlavičku jako prostý text.
Přímé použití $_SERVER je jednoduchý a funguje v jakémkoli rozhraní SAPI, kde PHP vystavilo hlavičku jako proměnnou prostředí. Musíte však znát přesný název klíče nebo si jej sami vytvořit.
Vytvoření úplného seznamu hlaviček z $_SERVER
Pokud chcete všechny hlavičky, ale nemůžete se spolehnout na getallheaders, můžete je rekonstruovat skenováním $_SERVER pro klíče začínající na HTTP_.
Zde je malý pomocník, který:
- Obraty
HTTP_ACCEPT_LANGUAGEnaAccept-Language - shromáždí všechny takové hlavičky do asociativního pole
- Přidává
Content-TypeaContent-Length, které mohou být vystaveny bezHTTP_předpona
<?php function headers_from_server(): array{ $headers = []; foreach ($_SERVER as $name => $value) { if (str_starts_with($name, 'HTTP_')) { $headerName = substr($name, 5); // remove "HTTP_" $headerName = str_replace('_', ' ', $headerName); $headerName = ucwords(strtolower($headerName)); $headerName = str_replace(' ', '-', $headerName); $headers[$headerName] = $value; } } // Some headers are not prefixed with HTTP_ if (isset($_SERVER['CONTENT_TYPE'])) { $headers['Content-Type'] = $_SERVER['CONTENT_TYPE']; } if (isset($_SERVER['CONTENT_LENGTH'])) { $headers['Content-Length'] = $_SERVER['CONTENT_LENGTH']; } return $headers;} $headers = headers_from_server(); foreach ($headers as $name => $value) { echo $name . ': ' . $value . PHP_EOL;}
Body, kterých je třeba si všimnout:
str_starts_withvyžaduje PHP 8.- Transformace normalizuje názvy záhlaví do společného tvaru
Title-Case-Format. - Díky tomu získáte konzistentní řadu záhlaví i v prostředích, kde se
getallheadersnení definován.
Mějte na paměti, že některá nastavení serverů mohou stále skrývat určité hlavičky (např. Authorization), pokud není nakonfigurováno jejich předávání do prostředí CGI.
Krátká poznámka o prostředí a CLI
Hlavičky požadavků existují pouze pro skutečné požadavky HTTP. Pokud skript spustíte z příkazového řádku:
$_SERVERnebude obsahovat smysluplné položky hlavičky HTTP pro běžné volání CLI.getallheadersorapache_request_headersnemusí být vůbec definován nebo nemusí vracet nic užitečného, pokud neprobíhá žádný skutečný požadavek HTTP.
Každý kód, který se spoléhá na záhlaví, by tedy měl:
- být proveden pouze v kontextu HTTP, nebo
- Buďte obranní a řešte případy, kdy chybí hlavičky nebo nejsou k dispozici funkce.