Získání hlaviček požadavků v jazyce PHP

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, ja...

Poptat web

27. 11. 2025

Získání hlaviček požadavků v jazyce PHP

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 $_SERVER pojmenová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 zahrnuje Authorization záhlaví, kde $_SERVER sá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_case vytvoří 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 $_SERVER pomocí 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_LANGUAGE na Accept-Language
  • shromáždí všechny takové hlavičky do asociativního pole
  • Přidává Content-Type a Content-Length, které mohou být vystaveny bez HTTP_ 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_with vyž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 getallheaders není 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:

  • $_SERVER nebude obsahovat smysluplné položky hlavičky HTTP pro běžné volání CLI.
  • getallheaders or apache_request_headers nemusí 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.

Původní článek publikoval Nabil Hassen.