Obtenga la URL completa en PHP
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.
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_HOST
valoresREQUEST_URI
arbitrarios. 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.
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:password
desde 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_id
cliente (navegador) no envía el mensaje al servidor y no se agregará a la URL completa. $_GET
solo contendráfoo=bar2
una URL como/example?foo=bar1&foo=bar2
.- Algunos CMS y entornos reescribirán
$_SERVER['REQUEST_URI']
y devolverán/example?foo=bar2
una 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_HOST
si no planea utilizar proxies o balanceadores. - La especificación dice que el
Host
encabezado 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$_SERVER
variables 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
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_SEPARATOR
devuelve\
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/
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 .