¿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?

CtrlDot
fuente
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'].

Vinko Vrsalovic
fuente
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;
Tyler Carter
fuente
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 :)

cwd
fuente
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;
Suresh Kumar
fuente
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.

Avery
fuente
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;
}
Jrgns
fuente
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.

Peter Bailey
fuente
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']

Adam Hopkinson
fuente
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];
beniwal
fuente
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/"
//      }
SpYk3HH
fuente
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.

Gajus
fuente
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();
?>
Desarrolladores de Joomla
fuente
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"]
Hüseyin Yağlı
fuente
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 <[email protected]>
 */

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'])), '/'));
}
usuario1949536
fuente