Introduzione
Quando si parla di superglobali in PHP, molte persone pensano subito a $_GET, $_POST o $_SESSION. In realtà, una delle superglobali più utili e spesso sottovalutate è $_SERVER, perché permette di leggere informazioni fondamentali sull’ambiente di esecuzione e sulla richiesta HTTP in corso.
In questo tutorial vedremo un sotto-argomento molto pratico: usare $_SERVER per costruire un piccolo sistema di routing basato sull’URL richiesta. È un caso reale, utile sia in progetti semplici sia come base per comprendere il funzionamento dei framework moderni.
Capire come estrarre il percorso richiesto, distinguere il metodo HTTP e riconoscere parametri importanti ci aiuta a scrivere codice più ordinato, più sicuro e più facile da mantenere.
Codice completo
<?php
declare(strict_types=1);
// Recupera l´URI richiesta dal browser.
// Esempio: /prodotti/42?ref=homepage
$requestUri = $_SERVER[´REQUEST_URI´] ?? ´/´;
// Recupera il metodo HTTP usato nella richiesta.
// Esempi: GET, POST, PUT, DELETE
$requestMethod = $_SERVER[´REQUEST_METHOD´] ?? ´GET´;
// Separa il path dalla query string.
// parse_url() è utile perché ci restituisce solo il percorso, senza i parametri.
$path = parse_url($requestUri, PHP_URL_PATH) ?? ´/´;
// Normalizza il percorso rimuovendo eventuali slash finali.
// Così /prodotti/ e /prodotti diventano equivalenti.
$path = rtrim($path, ´/´);
if ($path === ´´) {
$path = ´/´;
}
// Definizione delle "rotte" disponibili.
$routes = [
´GET´ => [
´/´ => fn() => ´<h1>Home page</h1><p>Benvenuto nel sito.</p>´,
´/chi-siamo´ => fn() => ´<h1>Chi siamo</h1><p>Informazioni sull´azienda.</p>´,
´/prodotti´ => fn() => ´<h1>Prodotti</h1><p>Elenco dei prodotti disponibili.</p>´,
],
´POST´ => [
´/contatti´ => fn() => ´<h1>Contatti ricevuti</h1><p>Il modulo è stato inviato correttamente.</p>´,
],
];
// Controlla se esiste una rotta per il metodo e il path richiesti.
if (isset($routes[$requestMethod][$path])) {
echo $routes[$requestMethod][$path]();
exit;
}
// Gestione del caso "404 Not Found".
http_response_code(404);
echo ´<h1>404 - Pagina non trovata</h1>´;
echo ´<p>La rotta richiesta non esiste.</p>´;
// Per debugging, possiamo mostrare alcune informazioni della richiesta.
// In produzione, evita di esporre dettagli tecnici all´utente.
echo ´<hr>´;
echo ´<pre>´;
echo ´Metodo: ´ . htmlspecialchars($requestMethod) . PHP_EOL;
echo ´URI: ´ . htmlspecialchars($requestUri) . PHP_EOL;
echo ´Path: ´ . htmlspecialchars($path) . PHP_EOL;
echo ´</pre>´;
?> Spiegazione
Il cuore dell’esempio è $_SERVER[´REQUEST_URI´], che contiene la URI completa richiesta dal client. Per esempio, se l’utente visita:
/prodotti/42?ref=homepage
allora REQUEST_URI conterrà proprio quella stringa. Tuttavia, per il routing non ci interessa quasi mai la query string, ma solo il percorso. Per questo usiamo parse_url(..., PHP_URL_PATH), che estrae la parte di path:
- /prodotti/42?ref=homepage → /prodotti/42
- /chi-siamo → /chi-siamo
In seguito normalizziamo il percorso con rtrim($path, ´/´), così evitiamo problemi tra URL scritte con o senza slash finale.
Perché controllare anche il metodo HTTP
Con $_SERVER[´REQUEST_METHOD´] possiamo sapere se la richiesta è stata inviata con GET, POST e altri metodi. Questo è importante perché la stessa URL può avere comportamenti diversi in base al metodo usato.
Per esempio:
- GET /contatti potrebbe mostrare il form di contatto
- POST /contatti potrebbe salvare i dati inviati
Separare il comportamento in base al metodo è una buona pratica, perché rende il codice più chiaro e aderente al protocollo HTTP.
La struttura delle rotte
Nel nostro esempio usiamo un array multidimensionale per definire le rotte disponibili. Ogni metodo HTTP contiene una lista di path associati a una funzione anonima. Questo approccio è semplice ma molto efficace per piccoli progetti o per imparare il concetto di routing.
Quando il path richiesto esiste nell’array, eseguiamo la funzione associata. Se non esiste, rispondiamo con un errore 404.
Perché usare funzioni anonime
Le funzioni anonime permettono di associare un comportamento direttamente alla rotta, senza creare subito una classe o un sistema più complesso. Questo rende l’esempio compatto e leggibile. In un progetto reale, potresti sostituirle con controller o metodi di classe.
Gestione dell’errore 404
Se la rotta non viene trovata, impostiamo il codice HTTP con http_response_code(404). Questo è importante perché il browser e i motori di ricerca devono capire che la pagina non esiste. Non basta scrivere un messaggio visivo: serve anche un codice di stato corretto.
Best practice
- Usa $_SERVER con cautela: alcune chiavi possono non essere sempre presenti, quindi è meglio prevedere valori di fallback con ??.
- Non fidarti mai dei dati ricevuti: anche se $_SERVER contiene informazioni utili, alcune variabili dipendono dall’ambiente o dalla configurazione del server.
- Separa il path dalla query string: per il routing usa solo il percorso, non i parametri dopo ?.
- Normalizza le URL: gestisci slash finali, maiuscole/minuscole e formati coerenti per evitare bug difficili da individuare.
- Imposta sempre gli status code corretti: 200, 404, 405 e altri codici aiutano client e strumenti esterni a interpretare bene la risposta.
- Evita di mostrare dettagli tecnici in produzione: informazioni come URI complete, percorsi interni o variabili di debug possono essere utili in sviluppo, ma non devono essere esposte agli utenti finali.
- Escapa sempre l’output quando stampi dati provenienti dalla richiesta, usando ad esempio htmlspecialchars().
Riepilogo
$_SERVER è una superglobale fondamentale per leggere informazioni sulla richiesta HTTP e sull’ambiente PHP. In questo tutorial l’abbiamo usata per costruire un mini router, un esempio pratico che mostra come estrarre il path richiesto, controllare il metodo HTTP e gestire una risposta 404 in modo corretto.
Questo approccio non sostituisce i framework moderni, ma aiuta a capire cosa succede “dietro le quinte”. Una volta compreso questo meccanismo, sarà molto più semplice lavorare con Laravel, Symfony o con architetture MVC personalizzate.
Il concetto chiave da portare a casa è semplice: le superglobali non servono solo a leggere dati, ma anche a prendere decisioni sul flusso dell’applicazione.
Approfondisci con risorse ufficiali
- Manuale PHP su $_SERVER: documentazione ufficiale delle variabili disponibili nell’array superglobale.
- parse_url(): funzione ufficiale per analizzare URL e URI.
- http_response_code(): per impostare correttamente il codice di stato HTTP.
- htmlspecialchars(): utile per proteggere l’output HTML da caratteri speciali.
- HTTP status codes: per comprendere i codici 2xx, 4xx e 5xx usati nelle risposte web.
