Detective PHP: ¿qué se esconde detrás de HTTP_HOST y SERVER_NAME?
\n\nSi alguna vez has explorado el array superglobal $_SERVER en PHP, seguro que has visto dos claves muy similares: HTTP_HOST y SERVER_NAME. A simple vista parecen lo mismo — el nombre del servidor. Pero los desarrolladores experimentados saben que el diablo está en los detalles. Este tema ha acumulado miles de visitas en Stack Overflow, y no es casualidad. Elegir mal puede provocar errores en redirecciones, fallos en peticiones entre dominios e incluso vulnerabilidades de seguridad.
En este artículo no solo enumeraremos definiciones aburridas. Vamos a hacer una verdadera investigación: veremos de dónde vienen estos valores, cómo se comportan en diferentes servidores (Apache, Nginx) y, lo más importante, cuándo usar cada uno. Abróchate el cinturón, que esto se pone interesante.
\n\n¿Qué es HTTP_HOST?
\nHTTP_HOST es el valor de la cabecera Host que el navegador (o cualquier cliente HTTP) envía al servidor en la petición. Esta cabecera es obligatoria en HTTP/1.1 y contiene el nombre de dominio y, opcionalmente, el puerto.
Ejemplo de petición del navegador:
\nGET /page.php HTTP/1.1\nHost: pythonlib.es:8080\nUser-Agent: Mozilla/5.0\n...\nEn PHP, este valor se almacena en $_SERVER['HTTP_HOST']. Atención: es un valor no verificado. El cliente puede enviar cualquier texto en la cabecera Host, por ejemplo, sitio-malicioso.com o 192.168.1.1. Aquí está el verdadero peligro.
¿Qué es SERVER_NAME?
\nSERVER_NAME es el valor que establece el propio servidor web según su configuración. Normalmente se obtiene de la directiva ServerName en Apache o server_name en Nginx. Es el nombre del host virtual que ha procesado la petición.
Ejemplo de configuración Apache:
\n<VirtualHost *:80>\n ServerName pythonlib.es\n DocumentRoot /var/www/pythonlib\n</VirtualHost>\nEn este caso, $_SERVER['SERVER_NAME'] será pythonlib.es. A diferencia de HTTP_HOST, este valor lo controla el administrador del servidor, no el cliente. Pero hay un matiz: SERVER_NAME puede no incluir el puerto (depende de la configuración UseCanonicalName).
Diferencias clave en tabla comparativa
\nPara que quede más claro, resumimos todo en una tabla:
\n| Parámetro | \nHTTP_HOST | \nSERVER_NAME | \n
|---|---|---|
| Origen | \nCabecera HTTP de la petición del cliente | \nConfiguración del servidor web | \n
| Control | \nCliente (puede ser falsificado) | \nAdministrador del servidor | \n
| Puerto | \nIncluye puerto si no es estándar (ej. sitio.com:8080) | \n Generalmente sin puerto (depende de UseCanonicalName) | \n
| Fiabilidad | \nBaja (no confíes sin validar) | \nAlta (pero no absoluta) | \n
| Uso recomendado | \nRedirecciones, enlaces para el usuario | \nLógica interna, seguridad | \n
¿Cuándo usar cada uno? Ejemplos prácticos
\nAhora vamos a lo importante: el código. Veamos tres escenarios típicos.
\n\n