Gestire <strong>$_SERVER</strong> per il controllo degli header HTTP in PHP

by theArchitect
SHARE
Gestire <strong>$_SERVER</strong> per il controllo degli header HTTP in PHP
© Guida-HTML5.it

Introduzione

Quando si parla di superglobali in PHP, di solito si pensa subito a $_GET, $_POST o $_SESSION. In realtà, $_SERVER è una delle più utili in assoluto perché espone molte informazioni sull’ambiente di esecuzione e sulla richiesta HTTP corrente.

In questo tutorial ci concentriamo su un sotto-argomento pratico e molto usato: leggere e controllare gli header HTTP della richiesta tramite $_SERVER. È un tema importante quando devi:

  • verificare il tipo di contenuto inviato dal client;
  • gestire richieste API;
  • controllare autenticazione basata su token;
  • leggere header personalizzati inviati dal frontend o da altri servizi;
  • scrivere codice più robusto e sicuro.

Molti sviluppatori usano direttamente $_SERVER per leggere i valori degli header, ma non sempre conoscono la convenzione corretta di PHP, né i limiti di questo approccio. Qui vedremo un esempio reale e una strategia pulita per ottenere gli header in modo affidabile.

Codice completo

<?php
declare(strict_types=1);

/**
 * Restituisce il valore di un header HTTP letto da $_SERVER.
 * Esempio: getHeader(´Content-Type´) => $_SERVER[´CONTENT_TYPE´]
 */
function getHeader(string $name): ?string
{
    // Gli header HTTP in $_SERVER arrivano spesso in maiuscolo
    // e con trattini trasformati in underscore.
    $key = ´HTTP_´ . strtoupper(str_replace(´-´, ´_´, $name));

    // Alcuni header speciali non iniziano con HTTP_
    $specialKeys = [
        ´CONTENT_TYPE´   => ´CONTENT_TYPE´,
        ´CONTENT_LENGTH´ => ´CONTENT_LENGTH´,
        ´CONTENT_MD5´    => ´CONTENT_MD5´,
    ];

    if (isset($specialKeys[strtoupper($name)])) {
        $key = $specialKeys[strtoupper($name)];
    }

    return $_SERVER[$key] ?? null;
}

/**
 * Verifica se la richiesta accetta JSON.
 */
function acceptsJson(): bool
{
    $accept = getHeader(´Accept´);

    if ($accept === null) {
        return false;
    }

    return stripos($accept, ´application/json´) !== false;
}

/**
 * Controlla se il client ha inviato un token Bearer nell´header Authorization.
 */
function getBearerToken(): ?string
{
    $authorization = getHeader(´Authorization´);

    if ($authorization === null) {
        return null;
    }

    if (!preg_match(´/^Bearers+(.+)$/i´, $authorization, $matches)) {
        return null;
    }

    return trim($matches[1]);
}

/**
 * Esempio di endpoint semplice.
 */
header(´Content-Type: application/json; charset=utf-8´);

$response = [
    ´method´ => $_SERVER[´REQUEST_METHOD´] ?? ´UNKNOWN´,
    ´accepts_json´ => acceptsJson(),
    ´content_type´ => getHeader(´Content-Type´),
    ´authorization_present´ => getHeader(´Authorization´) !== null,
    ´bearer_token´ => getBearerToken(),
];

// Esempio di controllo: accetta solo richieste POST con JSON
if (($response[´method´] ?? ´´) !== ´POST´) {
    http_response_code(405);
    echo json_encode([
        ´error´ => ´Metodo non consentito. Usa POST.´,
    ], JSON_PRETTY_PRINT);
    exit;
}

if (!acceptsJson()) {
    http_response_code(415);
    echo json_encode([
        ´error´ => ´Formato non supportato. Atteso application/json nell’header Accept.´,
    ], JSON_PRETTY_PRINT);
    exit;
}

if (getBearerToken() === null) {
    http_response_code(401);
    echo json_encode([
        ´error´ => ´Token Bearer mancante o non valido.´,
    ], JSON_PRETTY_PRINT);
    exit;
}

echo json_encode([
    ´message´ => ´Richiesta valida´,
    ´request´ => $response,
], JSON_PRETTY_PRINT);

Spiegazione

La superglobale $_SERVER contiene molte informazioni utili sulla richiesta e sul server. Tra queste ci sono anche gli header HTTP, ma con una particolarità importante: PHP li normalizza.

1. Come PHP espone gli header in $_SERVER

Gli header inviati dal client non compaiono sempre con il loro nome originale. PHP li converte spesso in questo formato:

  • Accept diventa $_SERVER[´HTTP_ACCEPT´]
  • Authorization diventa $_SERVER[´HTTP_AUTHORIZATION´] in alcuni ambienti
  • X-Request-Id diventa $_SERVER[´HTTP_X_REQUEST_ID´]

Ci sono però eccezioni. Alcuni header, come Content-Type e Content-Length, non usano il prefisso HTTP_. Per questo nel codice abbiamo creato la funzione getHeader(), che gestisce sia i casi standard sia quelli speciali.

2. Perché leggere gli header è utile

In un’applicazione reale, leggere gli header ti permette di prendere decisioni rapide prima ancora di processare i dati del body. Per esempio:

  • se il client non accetta JSON, puoi rispondere con un errore 415;
  • se manca il token Bearer, puoi bloccare l’accesso con un 401;
  • se il metodo non è quello atteso, puoi rispondere con un 405.

Questo approccio rende il codice più chiaro e migliora la manutenzione dell’API.

3. La funzione getHeader()

La funzione getHeader() riceve il nome dell’header in formato “umano”, per esempio Content-Type o Authorization, e lo converte nel nome usato da PHP dentro $_SERVER.

Il passaggio chiave è questo:

  • trasformare il nome in maiuscolo;
  • sostituire i trattini con underscore;
  • aggiungere il prefisso HTTP_ quando necessario.

Questa piccola astrazione evita di scrivere direttamente codice fragile come $_SERVER[´HTTP_X_CUSTOM_HEADER´] ?? null ovunque nel progetto.

4. Controllo dell’header Accept

La funzione acceptsJson() legge l’header Accept e verifica se contiene application/json. Questo è utile quando vuoi costruire endpoint che rispondono solo a client compatibili con JSON.

Non è una validazione “assoluta” del client, ma è un buon filtro iniziale per decidere la risposta HTTP più corretta.

5. Estrazione del token Bearer

Molte API usano l’header Authorization con schema Bearer. La funzione getBearerToken() controlla che l’header esista e poi estrae il token con una regex semplice.

Questo è un passaggio fondamentale quando costruisci sistemi di autenticazione basati su token, perché ti evita di propagare valori non validi nel resto dell’applicazione.

Best practice

  • Non leggere direttamente $_SERVER ovunque: centralizza la logica in funzioni dedicate, come getHeader().
  • Considera le differenze tra ambienti: alcuni server espongono Authorization in modo diverso; testa sempre in locale e in produzione.
  • Controlla sempre l’esistenza della chiave: usa ?? null o isset() per evitare notice e warning.
  • Non fidarti ciecamente degli header del client: possono essere falsificati facilmente. Usali per il routing logico o per il parsing, ma non come unica fonte di sicurezza.
  • Rispondi con codici HTTP corretti: 405 per metodo non consentito, 415 per media type non supportato, 401 per non autenticato.
  • Se lavori con API, separa la lettura degli header dalla logica di business: il codice sarà più testabile e più pulito.

Riepilogo

La superglobale $_SERVER non serve solo a conoscere il dominio o il metodo della richiesta: è anche un ottimo punto di accesso per leggere gli header HTTP. In questo tutorial hai visto come:

  • mappare correttamente gli header dentro $_SERVER;
  • creare una funzione riutilizzabile per recuperarli;
  • verificare se una richiesta accetta JSON;
  • estrarre un token Bearer dall’header Authorization;
  • gestire risposte HTTP coerenti in un endpoint PHP.

Se vuoi scrivere applicazioni PHP moderne, specialmente API, imparare a usare bene gli header tramite $_SERVER è una competenza molto concreta e utile ogni giorno.

Approfondisci con risorse ufficiali

  • Manuale PHP - $_SERVER: documentazione ufficiale sulla superglobale e sulle variabili disponibili.
  • Manuale PHP - headers_list(): utile per capire quali header sta inviando PHP.
  • Manuale PHP - header(): per impostare correttamente gli header di risposta.
  • Manuale PHP - filter_var(): utile quando devi combinare lettura degli header e validazione dei dati.
  • RFC HTTP: per approfondire il significato dei principali header e dei codici di stato.

SHARE