URL completo en PHP: cómo obtenerlo rápido y sin errores

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

¿Cómo obtener la URL completa en PHP sin volverse loco?

\n\n

Cada desarrollador de PHP se ha enfrentado al menos una vez a la tarea: "¿Cómo obtengo la URL completa de la página actual?". Parecería que no podría ser más sencillo: tomar $_SERVER['HTTP_HOST'], agregar $_SERVER['REQUEST_URI'] y listo. Pero la realidad, como siempre, introduce sus correcciones. ¿HTTP o HTTPS? ¿Y si el puerto no es estándar? ¿Y si el sitio está detrás de un proxy? ¿Y si no solo necesitas obtenerla, sino hacerlo rápido, sin fugas de memoria y con miras al futuro?

\n\n

La pregunta "Get the full URL in PHP" en Stack Overflow ha acumulado miles de visitas y docenas de respuestas. Esto no es casualidad: el tema parece simple, pero tiene tantas trampas como un charco en primavera. Hoy analizaremos no solo "cómo hacerlo", sino cómo hacerlo correctamente, rápido y de forma confiable. ¡Allá vamos!

\n\n

¿Por qué copiar directamente de $_SERVER es malo?

\n\n

Los desarrolladores novatos a menudo escriben así:

\n\n
$url = 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
\n\n

A primera vista, funciona. Pero veamos los problemas:

\n
    \n
  • Sin HTTPS. Si el sitio funciona con HTTPS, obtendrá http:// y el navegador se quejará de contenido mixto.
  • \n
  • Puerto. Si el puerto no es estándar (por ejemplo, 8080), se perderá si no se usa $_SERVER['SERVER_PORT'].
  • \n
  • Proxies y balanceadores. Detrás de un proxy inverso (Nginx, Cloudflare), $_SERVER['HTTP_HOST'] puede no ser lo que ve el usuario.
  • \n
  • Seguridad. El valor de HTTP_HOST puede ser manipulado por un atacante (Host header injection).
  • \n
\n\n

En resumen, copiar y pegar de la primera respuesta en Stack Overflow no es la mejor opción. Escribamos una función correcta y eficiente.

\n\n

Función de referencia: obtenemos la URL completa correctamente

\n\n

Aquí hay una función confiable que considera todos los escenarios principales:

\n\n
function 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    // Consideramos encabezados del proxy (si confiamos en él)\n    $host = $_SERVER['HTTP_HOST'] ?? '';\n    if (empty($host) && !empty($_SERVER['SERVER_NAME'])) {\n        $host = $_SERVER['SERVER_NAME'];\n    }\n\n    // Verificación del puerto\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\n

¿Qué es importante aquí?

\n
    \n
  • Verificamos HTTPS — método estándar, funciona en el 99% de los casos.
  • \n
  • Consideramos SERVER_PORT — si el sitio está en un puerto no estándar, no lo perdemos.
  • \n
  • Opción de respaldo con SERVER_NAME — por si HTTP_HOST está vacío.
  • \n
  • No usamos $_SERVER['SCRIPT_URI'] — no está disponible en todos lados.
  • \n
\n\n

Optimización del rendimiento: cuando cada milisegundo cuenta

\n\n

Si llama a esta función en cada página o en un bucle, vale la pena pensar en la velocidad. Aquí hay algunos consejos:

\n\n

1. Almacenamiento en caché del resultado

\n

Si la URL no cambia dentro de una misma solicitud (y no cambia), guárdela en caché:

\n\n
function getFullUrlCached(): string {\n    static $url = null;\n    if ($url === null) {\n        $url = getFullUrl(); // usamos nuestra función anterior\n    }\n    return $url;\n}
\n\n

Una variable estática conserva el valor después de la primera llamada — sin cálculos repetidos.

\n\n

2. Evite operaciones innecesarias

\n

No use filt

Blogs

Book Recommendations