Pregunta Obtenga la URL completa en PHP


Uso 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, entonces, 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 ver cómo aparece en la barra de navegación en el navegador web, y no la ruta real del archivo en el servidor.


979
2017-07-20 21:29


origen


Respuestas:


Mira esto $_SERVER['REQUEST_URI'], es decir

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

(Tenga en cuenta que la sintaxis de cadena de doble cita es perfectamente correcto)

Si desea admitir HTTP y HTTPS, puede usar

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

Nota del editor: usando este código tiene implicaciones de seguridad. El cliente puede establecer HTTP_HOST y REQUEST_URI a cualquier valor arbitrario que quiera.


1623
2017-07-20 21:33



Versión corta para el enlace de salida 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 algunos detalles más sobre los problemas y casos extremos de el 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.

Estructura de URL:

esquema://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 o el fragmento (hash).
  • No mostrará el puerto predeterminado 80 para HTTP y el puerto 443 para HTTPS.
  • Solo probado con esquemas http y https.
  • los #fragment_id no es enviado al servidor por el cliente (navegador) y no se agregará a la URL completa.
  • $_GET solo contendrá foo=bar2 para una URL como /example?foo=bar1&foo=bar2.
  • Algunos CMS y entornos reescribirán $_SERVER['REQUEST_URI'] y volver /example?foo=bar2 para una URL como /example?foo=bar1&foo=bar2, utilizar $_SERVER['QUERY_STRING'] en este caso.
  • Tenga en cuenta que URI = URL + URN, pero debido al uso popular, URL ahora significa URI y URL.
  • Debes eliminar HTTP_X_FORWARDED_HOST si no planea usar proxies o equilibradores.
  • los especulación dice que el Host el 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']. Cualquier carácter no admitido es codificado por el navegador antes de enviarse.
  • $_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'] se establece por 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 de vacío o "encendido".
  • $_SERVER['SERVER_PORT']. El servidor solo acepta números permitidos como puertos.
  • $_SERVER['SERVER_PROTOCOL']. El servidor solo acepta ciertos protocolos.
  • $_SERVER['SERVER_NAME'] . Se configura manualmente en la configuración del servidor y no está disponible para IPv6 de acuerdo con kralyk.

Relacionado:

HTTP_HOST vs. SERVER_NAME
¿Se requiere el número de puerto en el parámetro de encabezado HTTP "host"?
https://stackoverflow.com/a/28049503/175071


357
2018-01-17 08:57



Para ese asunto, solo eche un vistazo a toda la matriz con print_r($_SERVER), verá todo lo que necesita allí :)


190
2017-07-20 21:35



Ejemplos de URL: https://example.com/subFolder/yourfile.php?var=blabla#12345

//built-in function 
$x = parse_url($url);
$x['scheme']               🡺 https
$x['host']                 🡺         example.com (or with WWW)
$x['path']                 🡺                    /subFolder/yourfile.php
$x['query']                🡺                                          var=blabla
$x['fragment']             🡺                                                     12345 // hashtag outputed only in case, when hashtag-containing string was manually passed to function, otherwise PHP is unable to recognise hashtags in $_SERVER

//built-in function  (with this function, I only recommend to pass `parse_url`s output as argument)
$A = pathinfo($url);
$B = pathinfo(parse_url($url)['path']);
$A['dirname']              🡺 https://example.com/subFolder
$B['dirname']              🡺                    /subFolder
$A['basename']             🡺                               yourfile.php?var=blabla#12345
$B['basename']             🡺                               yourfile.php
$A['extension']            🡺                                        php?var=blabla#12345
$B['extension']            🡺                                        php
$A['filename']             🡺                               yourfile
$B['filename']             🡺                               yourfile


//=================================================== //
//========== self-defined SERVER variables ========== //
//=================================================== //
$_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                                         //similar: $_SERVER["SERVER_PROTOCOL"] 
$_SERVER['HTTP_HOST']      🡺         example.com (or with WWW)             //similar: $_SERVER["ERVER_NAME"]
$_SERVER["REQUEST_URI"]    🡺                       /subFolder/yourfile.php?var=blabla
$_SERVER["QUERY_STRING"]   🡺                                               var=blabla
__FILE__                   🡺 /home/user/public_html/subFolder/yourfile.php
__DIR__                    🡺 /home/user/public_html/subFolder              //same: dirname(__FILE__)
$_SERVER["REQUEST_URI"]    🡺                       /subFolder/yourfile.php?var=blabla
parse_url($_SERVER["REQUEST_URI"], PHP_URL_PATH)🡺  /subFolder/yourfile.php 
$_SERVER["PHP_SELF"]       🡺                       /subFolder/yourfile.php

// ==================================================================//
//if "YOURFILE.php" is included in "PARENTFILE.php" , and you visit  "PARENTFILE.PHP?abc":
$_SERVER["SCRIPT_FILENAME"]🡺 /home/user/public_html/parentfile.php
$_SERVER["PHP_SELF"]       🡺                       /parentfile.php
$_SERVER["REQUEST_URI"]    🡺                       /parentfile.php?abc
__FILE__                   🡺 /home/user/public_html/subFolder/yourfile.php

// =================================================== //
// ================= handy variables ================= //
// =================================================== //
//If site uses HTTPS:
$HTTP_or_HTTPS = ((!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS']!=='off') || $_SERVER['SERVER_PORT']==443) ? 'https://':'http://' );            //in some cases, you need to add this condition too: if ('https'==$_SERVER['HTTP_X_FORWARDED_PROTO'])  ...

//To trim values to filename, i.e. 
basename($url)             🡺 yourfile.php

//excellent solution to find origin
$debug_files = debug_backtrace();       $initial_called_file = count($debug_files) ? $debug_files[count($debug_files) - 1]['file'] : __FILE__;

¡Darse cuenta!:

  • hastag (# ...) las partes de url no se pueden detectar desde PHP (lado del servidor). Para eso, usa Javascript.
  • DIRECTORY_SEPARATOR devoluciones \ para hostings tipo Windows, en lugar de /.



Para WordPress

//(let's say, if wordpress is installed in subdirectory:  http://example.com/wpdir/)
home_url()                      🡺 http://example.com/wpdir/        //if is_ssl() is true, then it will be "https"
get_stylesheet_directory_uri()  🡺 http://example.com/wpdir/wp-content/themes/THEME_NAME  [same: get_bloginfo('template_url') ]
get_stylesheet_directory()      🡺 /home/user/public_html/wpdir/wp-content/themes/THEME_NAME
plugin_dir_url(__FILE__)        🡺 http://example.com/wpdir/wp-content/themes/PLUGIN_NAME
plugin_dir_path(__FILE__)       🡺 /home/user/public_html/wpdir/wp-content/plugins/PLUGIN_NAME/  

171
2017-11-15 09:59



Aquí hay una solución usando un declaración ternaria, manteniendo el código mínimo:

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

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


54
2018-04-24 13:30



Mi método de plataforma cruzada favorito para encontrar la URL actual es:

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

39
2018-05-18 01:54



Simplemente use:

$uri = $_SERVER['REQUEST_SCHEME'] . '://' . $_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']

22
2017-12-09 09:07



function full_path()
{
    $s = &$_SERVER;
    $ssl = (!empty($s['HTTPS']) && $s['HTTPS'] == 'on') ? true:false;
    $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 = 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;
    $uri = $protocol . '://' . $host . $s['REQUEST_URI'];
    $segments = explode('?', $uri, 2);
    $url = $segments[0];
    return $url;
}

Nota: Acabo de hacer una actualización del código de "Timo Huovinen", por lo que no obtendrá ningún get en la URL. Esta URL es simple y elimina cosas como "? Hi = i & am = a & get".

Ejemplo:

http://www.website.com/index?get=information

se mostrará como:

http://www.website.com/index

¡A menos que use Get's para definir un contenido específico, entonces use su código! :-)


16
2017-10-26 13:15



Borrar el código, trabajando en todos los servidores web (Apache, nginx, IIS, ...):

$url = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' ? 'https' : 'http') . '://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];

13
2018-04-27 15:57



Aquí está mi solución: el código está inspirado en Depurador Tracy. Se modificó para admitir diferentes puertos de servidor. Puede obtener la URL actual completa que incluye $_SERVER['REQUEST_URI'] o solo la URL del servidor básico. Verifica mi función:

function getCurrentUrl($full = true) {
    if (isset($_SERVER['REQUEST_URI'])) {
        $parse = parse_url(
            (isset($_SERVER['HTTPS']) && strcasecmp($_SERVER['HTTPS'], 'off') ? 'https://' : 'http://') .
            (isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : (isset($_SERVER['SERVER_NAME']) ? $_SERVER['SERVER_NAME'] : '')) . (($full) ? $_SERVER['REQUEST_URI'] : null)
        );
        $parse['port'] = $_SERVER["SERVER_PORT"]; // Setup protocol for sure (80 is default)
        return http_build_url('', $parse);
    }
}

Aquí está el código de prueba:

// Follow $_SERVER variables was set only for test
$_SERVER['HTTPS'] = 'off'; // on
$_SERVER['SERVER_PORT'] = '9999'; // Setup
$_SERVER['HTTP_HOST'] = 'some.crazy.server.5.name:8088'; // Port is optional there
$_SERVER['REQUEST_URI'] = '/150/tail/single/normal?get=param';

echo getCurrentUrl();
// http://some.crazy.server.5.name:9999/150/tail/single/normal?get=param

echo getCurrentUrl(false);
// http://some.crazy.server.5.name:9999/

10
2017-08-07 10:41