¿Cómo puedo obtener la URL completa de la página actual en un servidor Windows / IIS?


137

Moví una instalación de WordPress a una nueva carpeta en un servidor Windows / IIS . Estoy configurando redireccionamientos 301 en PHP, pero no parece estar funcionando. Las URL de mis publicaciones tienen el siguiente formato:

http:://www.example.com/OLD_FOLDER/index.php/post-title/

No puedo entender cómo tomar la /post-title/parte de la URL.

$_SERVER["REQUEST_URI"]- que todos parecen recomendar - está devolviendo una cadena vacía. $_SERVER["PHP_SELF"]Solo está volviendo index.php. ¿Por qué es esto y cómo puedo solucionarlo?


24
Simplemente haga un print_r ($ _ SERVER) y vea qué datos están disponibles para usted. Si puede obtener la URL completa, puede llamar a pathinfo ($ url) para obtener el nombre de archivo.
gradbot

18
Cabe señalar que esta pregunta es sobre IIS, no sobre PHP en general. En Apache, solo usarías $ _SERVER ['REQUEST_URI'].
Michał Tatarynowicz

@Pies Ciertamente $ _SERVER ['REQUEST_URI'] es el camino a seguir ... pero cómo puedo obtener una parte específica del URI. Por ejemplo, tengo este URI: /Appointments/Administrator/events.php/219 ... cómo puedo obtener el número después de /events.php/
Dimitris Papageorgiou

posible duplicado de Obtener la URL completa en PHP
T.Todua

Respuestas:


135

Tal vez, porque estás bajo IIS,

$_SERVER['PATH_INFO']

es lo que desea, en función de las URL que solía explicar.

Para Apache, lo usarías $_SERVER['REQUEST_URI'].


hola al usar esto, ¿acabo de recibir el siguiente error? Notice: Undefined index: PATH_INFO in /home/tdpk/public_html/system/config.php on line 14
chhameed

66
¡Vaya! ¡Drat! Acabo de darme cuenta de que esta pregunta es sobre IIS y la estoy usando. Perdón por el voto negativo.
Jason S

63
$pageURL = (@$_SERVER["HTTPS"] == "on") ? "https://" : "http://";
if ($_SERVER["SERVER_PORT"] != "80")
{
    $pageURL .= $_SERVER["SERVER_NAME"].":".$_SERVER["SERVER_PORT"].$_SERVER["REQUEST_URI"];
} 
else 
{
    $pageURL .= $_SERVER["SERVER_NAME"].$_SERVER["REQUEST_URI"];
}
return $pageURL;

11
OP declaró claramente IIS - REQUEST_URI no está disponible bajo IIS
Tom Auger

1
Nunca debe usar las comillas mágicas a menos que sea absolutamente necesario en php.
Caso del

2
@TomAuger Debes mirar la línea de tiempo. El OP agregó esto mucho después de que respondí la pregunta. La pregunta original se hizo aproximadamente un año antes de que la respondiera.
Tyler Carter el

77
@Stan, no hay ningún beneficio de rendimiento neto al usar individuales sobre dobles. Ninguno, nadda, zip, cero. Es la historia de una vieja esposa de la era PHP3. Por favor, no realice un cambio tan trivial al contenido.
Charles

36

Para Apache:

'http'.(empty($_SERVER['HTTPS'])?'':'s').'://'.$_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI']


También puede usar en HTTP_HOSTlugar de SERVER_NAMEcomo lo comentó Herman. Vea esta pregunta relacionada para una discusión completa. En resumen, probablemente esté de acuerdo con el uso de cualquiera. Aquí está la versión 'host':

'http'.(empty($_SERVER['HTTPS'])?'':'s').'://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']


Para los paranoicos / Por qué importa

Por lo general, configuro ServerNameel VirtualHostporque quiero que esa sea ​​la forma canónica del sitio web. El $_SERVER['HTTP_HOST']se establece en función de los encabezados de solicitud. Si el servidor responde a alguno / todos los nombres de dominio en esa dirección IP, un usuario podría suplantar el encabezado, o peor, alguien podría apuntar un registro DNS a su dirección IP, y luego su servidor / sitio web estaría sirviendo un sitio web dinámico enlaces creados en una URL incorrecta. Si usa el último método, también debe configurar su vhosto configurar una .htaccessregla para hacer cumplir el dominio que desea servir, algo como:

RewriteEngine On
RewriteCond %{HTTP_HOST} !(^stackoverflow.com*)$
RewriteRule (.*) https://stackoverflow.com/$1 [R=301,L]
#sometimes u may need to omit this slash ^ depending on your server

Espero que ayude. El punto real de esta respuesta fue simplemente proporcionar la primera línea de código para aquellas personas que terminaron aquí cuando buscaban una forma de obtener la URL completa con apache :)


2
Esto debería usar en $_SERVER['HTTP_HOST']lugar de $_SERVER['SERVER_NAME']. Si hay una configuración de host virtual, SERVER_NAME mostrará ese nombre. Puede ser algo como lo *.example.comque no es válido.
Herman J. Radtke III


9

Use esta clase para que la URL funcione.

class VirtualDirectory
{
    var $protocol;
    var $site;
    var $thisfile;
    var $real_directories;
    var $num_of_real_directories;
    var $virtual_directories = array();
    var $num_of_virtual_directories = array();
    var $baseURL;
    var $thisURL;

    function VirtualDirectory()
    {
        $this->protocol = $_SERVER['HTTPS'] == 'on' ? 'https' : 'http';
        $this->site = $this->protocol . '://' . $_SERVER['HTTP_HOST'];
        $this->thisfile = basename($_SERVER['SCRIPT_FILENAME']);
        $this->real_directories = $this->cleanUp(explode("/", str_replace($this->thisfile, "", $_SERVER['PHP_SELF'])));
        $this->num_of_real_directories = count($this->real_directories);
        $this->virtual_directories = array_diff($this->cleanUp(explode("/", str_replace($this->thisfile, "", $_SERVER['REQUEST_URI']))),$this->real_directories);
        $this->num_of_virtual_directories = count($this->virtual_directories);
        $this->baseURL = $this->site . "/" . implode("/", $this->real_directories) . "/";
        $this->thisURL = $this->baseURL . implode("/", $this->virtual_directories) . "/";
    }

    function cleanUp($array)
    {
        $cleaned_array = array();
        foreach($array as $key => $value)
        {
            $qpos = strpos($value, "?");
            if($qpos !== false)
            {
                break;
            }
            if($key != "" && $value != "")
            {
                $cleaned_array[] = $value;
            }
        }
        return $cleaned_array;
    }
}

$virdir = new VirtualDirectory();
echo $virdir->thisURL;

10
¿No es esto un poco exagerado?
s3v3n

7

Añadir:

function my_url(){
    $url = (!empty($_SERVER['HTTPS'])) ?
               "https://".$_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI'] :
               "http://".$_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI'];
    echo $url;
}

Entonces solo llame a la my_urlfunción.


5

Utilizo la siguiente función para obtener la URL actual y completa. Esto debería funcionar en IIS y Apache.

function get_current_url() {

  $protocol = 'http';
  if ($_SERVER['SERVER_PORT'] == 443 || (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on')) {
    $protocol .= 's';
    $protocol_port = $_SERVER['SERVER_PORT'];
  } else {
    $protocol_port = 80;
  }

  $host = $_SERVER['HTTP_HOST'];
  $port = $_SERVER['SERVER_PORT'];
  $request = $_SERVER['PHP_SELF'];
  $query = isset($_SERVER['argv']) ? substr($_SERVER['argv'][0], strpos($_SERVER['argv'][0], ';') + 1) : '';

  $toret = $protocol . '://' . $host . ($port == $protocol_port ? '' : ':' . $port) . $request . (empty($query) ? '' : '?' . $query);

  return $toret;
}

Creo que argv no funcionará si no está utilizando un Apache o IIS basado en CGI. Probé su código anterior en Apache2 en modo normal (no en modo CGI) y estaba fallando porque $ _SERVER ['arv'] [0] no es un índice. Tenga en cuenta también que tengo activado el informe completo de errores de PHP y estos errores fueron errores de aviso.
Volomike

Funciona como un encanto, sólo necesita un poco de actualización para evitar errores en el parámetro de cadena de consulta: $query = isset($_SERVER['argv']) ? substr($_SERVER['argv'][0], strpos($_SERVER['argv'][0], ';') + 1) : '';. He actualizado tu respuesta para incluir esto.
Zuul

4

REQUEST_URI está configurado por Apache, por lo que no lo obtendrá con IIS. Intente hacer un var_dump o print_r en $ _SERVER y vea qué valores existen allí que pueda usar.


3

La parte del posttítulo de la URL está detrás de su index.phparchivo, que es una forma común de proporcionar URL amigables sin usar mod_rewrite. Por lo tanto, el posttítulo es en realidad parte de la cadena de consulta, por lo que debería poder obtenerlo usando $ _SERVER ['QUERY_STRING']


2

Use la siguiente línea en la parte superior de la página PHP donde está usando $_SERVER['REQUEST_URI']. Esto resolverá tu problema.

$_SERVER['REQUEST_URI'] = $_SERVER['PHP_SELF'] . '?' . $_SERVER['argv'][0];

1

¡Oh, la diversión de un fragmento!

if (!function_exists('base_url')) {
    function base_url($atRoot=FALSE, $atCore=FALSE, $parse=FALSE){
        if (isset($_SERVER['HTTP_HOST'])) {
            $http = isset($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) !== 'off' ? 'https' : 'http';
            $hostname = $_SERVER['HTTP_HOST'];
            $dir =  str_replace(basename($_SERVER['SCRIPT_NAME']), '', $_SERVER['SCRIPT_NAME']);

            $core = preg_split('@/@', str_replace($_SERVER['DOCUMENT_ROOT'], '', realpath(dirname(__FILE__))), NULL, PREG_SPLIT_NO_EMPTY);
            $core = $core[0];

            $tmplt = $atRoot ? ($atCore ? "%s://%s/%s/" : "%s://%s/") : ($atCore ? "%s://%s/%s/" : "%s://%s%s");
            $end = $atRoot ? ($atCore ? $core : $hostname) : ($atCore ? $core : $dir);
            $base_url = sprintf( $tmplt, $http, $hostname, $end );
        }
        else $base_url = 'http://localhost/';

        if ($parse) {
            $base_url = parse_url($base_url);
            if (isset($base_url['path'])) if ($base_url['path'] == '/') $base_url['path'] = '';
        }

        return $base_url;
    }
}

Tiene hermosos retornos como:

// A URL like http://stackoverflow.com/questions/189113/how-do-i-get-current-page-full-url-in-php-on-a-windows-iis-server:

echo base_url();    // Will produce something like: http://stackoverflow.com/questions/189113/
echo base_url(TRUE);    // Will produce something like: http://stackoverflow.com/
echo base_url(TRUE, TRUE); || echo base_url(NULL, TRUE); //Will produce something like: http://stackoverflow.com/questions/

// And finally:
echo base_url(NULL, NULL, TRUE);
// Will produce something like:
//      array(3) {
//          ["scheme"]=>
//          string(4) "http"
//          ["host"]=>
//          string(12) "stackoverflow.com"
//          ["path"]=>
//          string(35) "/questions/189113/"
//      }

0

¿Todos olvidaron http_build_url ?

http_build_url($_SERVER['REQUEST_URI']);

Cuando no se pasan parámetros http_build_url, asumirá automáticamente la URL actual. Yo esperaríaREQUEST_URI que me incluyeran también, aunque parece ser necesario para incluir los parámetros GET.

El ejemplo anterior devolverá la URL completa.


1
Esto requiere pecl_http.
Omar Abid el

@OmarAbid lo recomiendo. :-)
Gajus

Entiendo tu posición. Pero al crear scripts que se utilizarán en diferentes plataformas sobre las que no tiene control, debe elegir algo bastante estándar.
Omar Abid

1
Si está creando una biblioteca, depende de usted definir los requisitos. La pregunta original no aborda tal escenario en absoluto. Por lo tanto, tiene sentido nombrar todas las alternativas.
Gajus

0

He usado el siguiente código y obtengo el resultado correcto ...

<?php
    function currentPageURL() {
        $curpageURL = 'http';
        if ($_SERVER["HTTPS"] == "on") {
            $curpageURL.= "s";
        }
        $curpageURL.= "://";
        if ($_SERVER["SERVER_PORT"] != "80") {
            $curpageURL.= $_SERVER["SERVER_NAME"].":".$_SERVER["SERVER_PORT"].$_SERVER["REQUEST_URI"];
        } 
        else {
            $curpageURL.= $_SERVER["SERVER_NAME"].$_SERVER["REQUEST_URI"];
        }
        return $curpageURL;
    }
    echo currentPageURL();
?>

Funciona bien Si no tiene HTTPS, entonces desea eliminar su línea.

0

En mi servidor apache, esto me da la URL completa en el formato exacto que está buscando:

$_SERVER["SCRIPT_URI"]

0

¡Soporte de proxy inverso!

Algo un poco más robusto. Nota Solo funcionará en 5.3o más.

/*
 * Compatibility with multiple host headers.
 * Support of "Reverse Proxy" configurations.
 *
 * Michael Jett <mjett@mitre.org>
 */

function base_url() {

    $protocol = @$_SERVER['HTTP_X_FORWARDED_PROTO'] 
              ?: @$_SERVER['REQUEST_SCHEME']
              ?: ((isset($_SERVER["HTTPS"]) && $_SERVER["HTTPS"] == "on") ? "https" : "http");

    $port = @intval($_SERVER['HTTP_X_FORWARDED_PORT'])
          ?: @intval($_SERVER["SERVER_PORT"])
          ?: (($protocol === 'https') ? 443 : 80);

    $host = @explode(":", $_SERVER['HTTP_HOST'])[0]
          ?: @$_SERVER['SERVER_NAME']
          ?: @$_SERVER['SERVER_ADDR'];

    // Don't include port if it's 80 or 443 and the protocol matches
    $port = ($protocol === 'https' && $port === 443) || ($protocol === 'http' && $port === 80) ? '' : ':' . $port;

    return sprintf('%s://%s%s/%s', $protocol, $host, $port, @trim(reset(explode("?", $_SERVER['REQUEST_URI'])), '/'));
}
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.