Obtener la URL actual con PHP puede ser muy simple como esto:

$url = $_SERVER["HTTP_HOST"] . $_SERVER["REQUEST_URI"]

Si lo vamos a utilizar como link podríamos hacer esto:

// Nota: el resultado es protocol agnostic
$link = "//$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
$escaped_link = htmlspecialchars($link, ENT_QUOTES, 'UTF-8');
echo '<a href="'.$escaped_link.'">'.$escaped_link.'</a>';

Y si queremos algo más completo, podemos complicarlo bastante y acceder al protocolo utilizado, puerto, etc (fuente):

function url_origin($s, $use_forwarded_host=false) {

  $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 = ($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;

Entonces hay quien argumentará que utilizar $_SERVER['HTTP_HOST'] no es un método seguro, ya que es definido en las cabeceras de la solicitud, lo que implica que el cliente (navegador) puede enviar el valor que quiera, y que en su lugar habría que utilizar $_SERVER['SERVER_NAME'], ambos deberían contener el mismo valor pero $_SERVER['SERVER_NAME'] es definido por la configuración del servidor y el cliente no lo puede modificar. Utiliza el que necesites: la cabecera de la solicitud o la configuración del servidor. En el bloque de código anterior se utiliza primero $_SERVER['HTTP_HOST'] y si no está definido se utiliza $_SERVER['SERVER_NAME'] (tenlo en cuenta si lo vas a utilizar).

Pero la mayoría de las veces no hay que complicarse tanto pues se necesita sólo alguna de la información de la superglobal $_SERVER y no la URL solicitada como tal. En el manual PHP sobre $_SERVER puedes ver toda la información disponible en esta variable, o puedes hacer un var_dump( $_SERVER ) para ver la información disponible en tu propia web. Alguna de la más comúnmente utilizada, respecto a la URL, es:

$_SERVER[‘SERVER_NAME’] y $_SERVER[‘HTTP_HOST’]

Ambos contienen el host, lo que generalmente llamamos dominio. La diferencia entre ambos, como se mencionó antes, es que $_SERVER['SERVER_NAME'] toma el valor de la configuración del servidor y $_SERVER['HTTP_HOST'] toma el valor de las cabeceras HTTP de la solicitud realizada por el cliente. En teoría (y en la práctica) es posible que ambos no coincidan.

$_SERVER[‘REQUEST_URI’]

Se puede decir que es todo lo que hay después del dominio, incluyendo el query string. Por ejemplo, en la URL http://midominio.com/una/url/cualquiera?bar=foo el valor de $_SERVER['REQUEST_URI'] sería una/url/cualquiera?bar=foo. Hay que tener en cuenta que los identificadores de fragmento nunca son enviados al servidor, por ejemplo, si se solicita http://midominio.com/una/url#un-identificador, la parte #un-identificador no es enviada al servidor en la solicitud y no estará disponible en $_SERVER['REQUEST_URI']; los identificadores de fragmento si están disponibles en javascript.

$_SERVER[‘QUERY_STRING’]

Contiene la llamada cadena de consulta. Por ejemplo, en http://midominio.com/una/url/cualquiera?bar=foo&bar2=foo2, el query string es ?bar=foo&bar2=foo2, aunque generalmente se utiliza $_GET o $_REQUEST para acceder a las diferentes variables de la cadena de consulta y sus respectivos valores.

  • Soul of Xiora

    Muchas gracias, queria hacerte una consulta…

    hay alguna manera de que me muestre la url si ésta tiene agregados como ? o & o #

    Por ejemplo si yo tengo una url así

    http://www.midominio.com/productos.php#C1

    Me la puede mostrar con ese #C1, ya que probe y supe, ¿sabes de algo mas para que me muestre eso también?

    Saludos y gracias

    • Las cadenas tipo ?key=value&key2=value2 son los query strings que se tratan en el post.

      Pero todo lo que haya después de # (hash o identificador de fragmento) nunca se envía al servidor, así que NO se puede leer en PHP, sólo client side con JavaScript.

  • Crear Página Web | WebArt.es

    Gracias por tu Trabajo 😉

    Me ha funcionado 100% correctamente.

    Es justo lo que me ha pedido un cliente: recoger y enviar la URL desde la que se envía el formulario. Realmente, es muy útil cuando hay diferentes formularios en una página web y queremos saber desde cuál de ellos nos lo envía.

    Un saludo desde Barcelona!!