Obtenga la URL completa en PHP

Resuelto DiegoP. asked hace 54 años • 27 respuestas

Utilizo este código para obtener la URL completa:

$actual_link = 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF'];

El problema es que uso algunas máscaras en mi.htaccess , por lo que lo que vemos en la URL no siempre es la ruta real del archivo.

Lo que necesito es obtener la URL, lo que está escrito en la URL, nada más y nada menos: la URL completa.

Necesito saber cómo aparece en la barra de navegación del navegador web y no la ruta real del archivo en el servidor.

DiegoP. avatar Jan 01 '70 08:01 DiegoP.
Aceptado

Eche un vistazo a $_SERVER['REQUEST_URI'], es decir

$actual_link = "https://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";

(Tenga en cuenta que la sintaxis de la cadena entre comillas dobles es perfectamente correcta ).

Si desea admitir tanto HTTP como HTTPS, puede utilizar

$actual_link = (empty($_SERVER['HTTPS']) ? 'http' : 'https') . "://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";

⚠️ Este código tiene implicaciones de seguridad porque el cliente y el servidor pueden establecer HTTP_HOSTvalores REQUEST_URIarbitrarios. Es absolutamente necesario desinfectar ambos valores y realizar una validación de entrada adecuada (CWE-20). No deben utilizarse en ningún contexto de seguridad.

ax. avatar Jul 20 '2011 21:07 ax.

Versión corta para generar un enlace en una página web

$url =  "//{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}";

$escaped_url = htmlspecialchars( $url, ENT_QUOTES, 'UTF-8' );
echo '<a href="' . $escaped_url . '">' . $escaped_url . '</a>';

Aquí hay más detalles sobre los problemas y casos extremos del formato //example.com/path/

Versión completa

function url_origin( $s, $use_forwarded_host = false )
{
    $ssl      = ( ! empty( $s['HTTPS'] ) && $s['HTTPS'] == 'on' );
    $sp       = strtolower( $s['SERVER_PROTOCOL'] );
    $protocol = substr( $sp, 0, strpos( $sp, '/' ) ) . ( ( $ssl ) ? 's' : '' );
    $port     = $s['SERVER_PORT'];
    $port     = ( ( ! $ssl && $port=='80' ) || ( $ssl && $port=='443' ) ) ? '' : ':'.$port;
    $host     = ( $use_forwarded_host && isset( $s['HTTP_X_FORWARDED_HOST'] ) ) ? $s['HTTP_X_FORWARDED_HOST'] : ( isset( $s['HTTP_HOST'] ) ? $s['HTTP_HOST'] : null );
    $host     = isset( $host ) ? $host : $s['SERVER_NAME'] . $port;
    return $protocol . '://' . $host;
}

function full_url( $s, $use_forwarded_host = false )
{
    return url_origin( $s, $use_forwarded_host ) . $s['REQUEST_URI'];
}

$absolute_url = full_url( $_SERVER );
echo $absolute_url;

Esta es una versión muy modificada de http://snipplr.com/view.php?codeview&id=2734 (que ya no existe)

Estructura de URL:

esquema:// nombre de usuario:contraseña @dominio:puerto/ruta?query_string# fragment_id

Las partes en negrita no serán incluidas por la función.

Notas:

  • Esta función no incluye username:passworddesde una URL completa ni el fragmento (hash).
  • No mostrará el puerto predeterminado 80 para HTTP ni el puerto 443 para HTTPS.
  • Solo probado con esquemas http y https.
  • El #fragment_idcliente (navegador) no envía el mensaje al servidor y no se agregará a la URL completa.
  • $_GETsolo contendrá foo=bar2una URL como /example?foo=bar1&foo=bar2.
  • Algunos CMS y entornos reescribirán $_SERVER['REQUEST_URI']y devolverán /example?foo=bar2una URL como /example?foo=bar1&foo=bar2, utilícela $_SERVER['QUERY_STRING']en este caso.
  • Tenga en cuenta que URI = URL + URN, pero debido al uso popular, URL ahora significa tanto URI como URL.
  • Debe eliminarlo HTTP_X_FORWARDED_HOSTsi no planea utilizar proxies o balanceadores.
  • La especificación dice que el Hostencabezado debe contener el número de puerto a menos que sea el número predeterminado.

Variables controladas por el cliente (navegador):

  • $_SERVER['REQUEST_URI']. El navegador codifica todos los caracteres no admitidos antes de enviarlos.
  • $_SERVER['HTTP_HOST']y no siempre está disponible según los comentarios en el manual de PHP: http://php.net/manual/en/reserved.variables.php
  • $_SERVER['HTTP_X_FORWARDED_HOST']lo configuran los balanceadores y no se menciona en la lista de $_SERVERvariables en el manual de PHP.

Variables controladas por el servidor:

  • $_SERVER['HTTPS']. El cliente elige usar esto, pero el servidor devuelve el valor real vacío o "activado".
  • $_SERVER['SERVER_PORT']. El servidor sólo acepta números permitidos como puertos.
  • $_SERVER['SERVER_PROTOCOL']. El servidor sólo acepta ciertos protocolos.
  • $_SERVER['SERVER_NAME']. Se configura manualmente en la configuración del servidor y no está disponible para IPv6 según kralyk .

Relacionado:

¿Cuál es la diferencia entre HTTP_HOST y SERVER_NAME en PHP?
¿Se requiere el número de puerto en el parámetro del encabezado HTTP "Host"?
https://stackoverflow.com/a/28049503/175071

Timo Huovinen avatar Jan 17 '2012 08:01 Timo Huovinen

Ejemplos de: https://www.site.xyz/fold/my.php?var=bla#555

Aviso 1:

  • la #parte del hashtag se agregó manualmente en el siguiente fragmento de ejemplo de PHP solo con fines teóricos e ilustrativos; sin embargo, los lenguajes del lado del servidor (incluido PHP) no pueden detectarlos, porque las partes de los hashtags solo se reconocen en el navegador/javascript del lado del cliente...*

Aviso 2:

  • DIRECTORY_SEPARATORdevuelve \para el sistema operativo Windows, mientras que UNIX devuelve /.
========== PATHINFO (use for filepathes, not urls) ==========

$x = PATHINFO ($url);
$x['dirname']              🡺 https://www.site.xyz/fold
$x['basename']             🡺                           my.php?var=bla#555 // unsafe!
$x['extension']            🡺                              php?var=bla#555 // unsafe!
$x['filename']             🡺                           my

========== PARSE_URL (use for urls, not filepathes) ==========

$x = PARSE_URL ($url);
$x['scheme']               🡺 https
$x['host']                 🡺         www.site.xyz
$x['path']                 🡺                     /fold/my.php
$x['query']                🡺                                  var=bla
$x['fragment']             🡺                                          555

Variable global $_SERVIDOR

$_SERVER["DOCUMENT_ROOT"]  🡺 /home/user/public_html
$_SERVER["SERVER_ADDR"]    🡺 143.34.112.23
$_SERVER["SERVER_PORT"]    🡺 80 (or 443, etc..)
$_SERVER["REQUEST_SCHEME"] 🡺 https                           
$_SERVER["SERVER_PROTOCOL"]🡺 <same>
$_SERVER['HTTP_HOST']      🡺        www.site.xyz
$_SERVER["SERVER_NAME"]    🡺           <same>
$_SERVER["REQUEST_URI"]    🡺                    /fold/my.php?var=bla
$_SERVER["QUERY_STRING"]   🡺                                 var=bla

__FILE__                   🡺 /home/user/public_html/fold/my.php
$_SERVER["SCRIPT_FILENAME"]🡺 <same>                              // Note! it will show entry file's path, if `my.php` is not called directly.
__DIR__                    🡺 /home/user/public_html/fold
dirname(__FILE__)          🡺 <same>
$_SERVER["REQUEST_URI"]    🡺                       /fold/my.php?var=bla  // Note! it will show entry file's path, if `my.php` is not called directly.
parse_url($_SERVER["REQUEST_URI"], PHP_URL_PATH)🡺  /fold/my.php
$_SERVER["PHP_SELF"]       🡺                       /fold/my.php  // Note! it will show entry file's path, if `my.php` is not called directly.
// detect https
$is_HTTPS = ((!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS']!=='off') || $_SERVER['SERVER_PORT']==443);            //in some cases, you need to add this condition too: if ('https'==$_SERVER['HTTP_X_FORWARDED_PROTO']) 

Funciones PHP

dirname($url)              🡺 https://www.site.xyz/fold/
basename($url)             🡺                           my.php
debug_backtrace()          🡺 SHOWS FULL TRACE OF ALL INCLUDED FILES




<Para WordPress>

// (Let's say, if WordPress is installed in subdirectory:  http://site.xyz/sub/)
home_url()                      🡺 http://site.xyz/sub/        // If is_ssl() is true, then it will be "https"
get_stylesheet_directory_uri()  🡺 http://site.xyz/sub/wp-content/themes/THEME_NAME  [same: get_bloginfo('template_url') ]
get_stylesheet_directory()      🡺 /home/user/public_html/sub/wp-content/themes/THEME_NAME
plugin_dir_url(__FILE__)        🡺 http://site.xyz/sub/wp-content/themes/PLUGIN_NAME
plugin_dir_path(__FILE__)       🡺 /home/user/public_html/sub/wp-content/plugins/PLUGIN_NAME/
T.Todua avatar Nov 15 '2014 09:11 T.Todua

Aquí hay una solución que utiliza una declaración ternaria , manteniendo el código al mínimo:

$url = "http" . (($_SERVER['SERVER_PORT'] == 443) ? "s" : "") . "://" . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];

Esta es la forma más pequeña y sencilla de hacerlo, suponiendo que el servidor web esté utilizando el puerto estándar 443 para HTTPS .

honyovk avatar Apr 24 '2012 13:04 honyovk