Comment obtenir l'URL complet en PHP sans perdre la tête ?
\n\nChaque développeur PHP a déjà été confronté à la question : « Comment obtenir l'URL complet de la page actuelle ? ». Cela semble simple — prendre $_SERVER['HTTP_HOST'], ajouter $_SERVER['REQUEST_URI'] — et le tour est joué. Mais la réalité, comme toujours, apporte ses corrections. HTTP ou HTTPS ? Et si le port n'est pas standard ? Et si le site est derrière un proxy ? Et si on ne veut pas seulement l'obtenir, mais le faire rapidement, sans fuites mémoire et en prévision du futur ?
La question « Get the full URL in PHP » sur Stack Overflow a recueilli des milliers de vues et des dizaines de réponses. Ce n'est pas un hasard : le sujet semble simple, mais les pièges sont nombreux comme dans une flaque printanière. Aujourd'hui, nous allons voir non seulement « comment faire », mais comment le faire correctement, rapidement et de manière fiable. C'est parti !
\n\nPourquoi la simple copie depuis $_SERVER est-elle néfaste ?
\n\nLes développeurs débutants écrivent souvent ceci :
\n\n$url = 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];\n\nÀ première vue, cela fonctionne. Mais examinons les problèmes :
\n- \n
- Pas de HTTPS. Si le site fonctionne en HTTPS, vous obtiendrez
http://— et le navigateur se plaindra de contenu mixte. \n - Port. Si le port n'est pas standard (par exemple 8080), il sera perdu si vous n'utilisez pas
$_SERVER['SERVER_PORT']. \n - Proxy et équilibreurs de charge. Derrière un proxy inverse (Nginx, Cloudflare),
$_SERVER['HTTP_HOST']peut ne pas correspondre à ce que voit l'utilisateur. \n - Sécurité. La valeur de
HTTP_HOSTpeut être usurpée par un attaquant (Host header injection). \n
Bref, le copier-coller depuis la première réponse sur Stack Overflow n'est pas la meilleure solution. Écrivons une fonction correcte et performante.
\n\nFonction de référence : obtenir l'URL complet correctement
\n\nVoici une fonction fiable qui prend en compte tous les scénarios principaux :
\n\nfunction getFullUrl(): string {\n $protocol = 'http';\n if (\n (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off')\n || (int)$_SERVER['SERVER_PORT'] === 443\n ) {\n $protocol = 'https';\n }\n\n // Prise en compte des en-têtes du proxy (si on lui fait confiance)\n $host = $_SERVER['HTTP_HOST'] ?? '';\n if (empty($host) && !empty($_SERVER['SERVER_NAME'])) {\n $host = $_SERVER['SERVER_NAME'];\n }\n\n // Vérification du port\n $port = (int)$_SERVER['SERVER_PORT'];\n $portSuffix = '';\n if (\n ($protocol === 'http' && $port !== 80)\n || ($protocol === 'https' && $port !== 443)\n ) {\n $portSuffix = ':' . $port;\n }\n\n $uri = $_SERVER['REQUEST_URI'] ?? '/';\n\n return $protocol . '://' . $host . $portSuffix . $uri;\n}\n\nQu'est-ce qui est important ici ?
\n- \n
- Nous vérifions
HTTPS— méthode standard, fonctionne dans 99% des cas. \n - Nous prenons en compte
SERVER_PORT— si le site est sur un port non standard, nous ne le perdons pas. \n - Option de secours via
SERVER_NAME— au cas oùHTTP_HOSTserait vide. \n - Nous n'utilisons pas
$_SERVER['SCRIPT_URI']— il n'est pas présent partout. \n
Optimisation des performances : quand chaque milliseconde compte
\n\nSi vous appelez cette fonction sur chaque page ou dans une boucle, il faut penser à la vitesse. Voici quelques astuces :
\n\n1. Mise en cache du résultat
\nSi l'URL ne change pas au cours d'une même requête (et elle ne change pas), mettez-la en cache :
\n\nfunction getFullUrlCached(): string {\n static $url = null;\n if ($url === null) {\n $url = getFullUrl(); // on utilise notre fonction ci-dessus\n }\n return $url;\n}\n\nUne variable statique conserve la valeur après le premier appel — pas de calculs répétés.
\n\n2. Évitez les opérations inutiles
\nN'utilisez pas filt