Como posso obter o URL completo da página atual em um servidor Windows / IIS?

137

Mudei uma instalação do WordPress para uma nova pasta em um servidor Windows / IIS . Estou configurando 301 redirecionamentos em PHP, mas não parece estar funcionando. Meus URLs de postagem têm o seguinte formato:

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

Não consigo descobrir como pegar a /post-title/parte da URL.

$_SERVER["REQUEST_URI"]- que todo mundo parece recomendar - está retornando uma string vazia. $_SERVER["PHP_SELF"]está apenas voltando index.php. Por que isso e como posso corrigi-lo?

CtrlDot
fonte
24
Basta fazer um print_r ($ _ SERVER) e ver quais dados estão disponíveis para você. Se você conseguir o URL completo, poderá chamar pathinfo ($ url) para obter o nome do arquivo.
gradbot
18
Deve-se notar que esta pergunta é sobre IIS, e não PHP em geral. No Apache, você usaria $ _SERVER ['REQUEST_URI'].
Michał Tatarynowicz 04/08/09
@Pies Certamente $ _SERVER ['REQUEST_URI'] é o caminho a percorrer ... mas como posso pegar uma parte específica do URI.Por exemplo, eu tenho esse URI: /Appointments/Administrator/events.php/219 ... como eu posso pegar o número após /events.php/
Dimitris Papageorgiou
possível duplicata de obter o URL completo em PHP
T.Todua

Respostas:

135

Talvez, porque você esteja no IIS,

$_SERVER['PATH_INFO']

é o que você deseja, com base nos URLs usados ​​para explicar.

Para o Apache, você usaria $_SERVER['REQUEST_URI'].

Vinko Vrsalovic
fonte
oi usando isso eu acabei de receber o seguinte erro? Notice: Undefined index: PATH_INFO in /home/tdpk/public_html/system/config.php on line 14
amigos estão dizendo sobre chhameed
6
oops, drat - acabei de perceber que esta pergunta é sobre IIS, e eu estou usando. Desculpe pelo 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
fonte
11
OP declarou claramente o IIS - REQUEST_URI não está disponível no IIS
Tom Auger
1
Você nunca deve usar magicquotes, a menos que seja absolutamente necessário no php.
Case
2
@ TomAuger Você precisa olhar para a linha do tempo. O OP foi adicionado muito tempo depois de eu responder à pergunta. A pergunta original foi feita aproximadamente um ano antes de eu respondê-la.
Tyler Carter #
7
@ Stan, não há benefício líquido de desempenho no uso de singles sobre duplos. Nenhum, nadda, zip, zero. É um conto antigo da era PHP3. Por favor, não faça uma manipulação tão trivial do conteúdo.
Charles
36

Para o Apache:

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


Você também pode usar em HTTP_HOSTvez de SERVER_NAMEcomo Herman comentou. Veja esta pergunta relacionada para uma discussão completa. Em suma, você provavelmente está bem em usar qualquer um. Aqui está a versão 'host':

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


Para os paranóicos / por que é importante

Normalmente, defino ServerNameno VirtualHostporque quero que essa seja a forma canônica do site. O $_SERVER['HTTP_HOST']é definido com base nos cabeçalhos da solicitação. Se o servidor responder a qualquer / todos os nomes de domínio nesse endereço IP, um usuário poderá falsificar o cabeçalho, ou pior, alguém poderá apontar um registro DNS para o seu endereço IP e, em seguida, seu servidor / site estará disponibilizando um site com dinâmica links criados em um URL incorreto. Se você usar o último método, também deverá configurar vhostou definir uma .htaccessregra para impor o domínio que deseja exibir, 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 ajude. O ponto real desta resposta era apenas fornecer a primeira linha de código para as pessoas que acabaram aqui quando procuravam uma maneira de obter o URL completo com o apache :)

cwd
fonte
2
Isso deve ser usado em $_SERVER['HTTP_HOST']vez de $_SERVER['SERVER_NAME']. Se houver uma configuração de host virtual, SERVER_NAME mostrará esse nome. Pode ser algo parecido *.example.comque não é válido.
Herman J. Radtke III
9

Use esta classe para fazer com que a 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;
Sureshkumar
fonte
10
isso não é um pouco exagerado?
S3v3n
7

Adicionar:

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

Em seguida, basta chamar a my_urlfunção.

Avery
fonte
5

Eu uso a seguinte função para obter o URL completo atual. Isso deve funcionar no IIS e no 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
fonte
argv não funcionará se você não estiver usando um Apache ou IIS baseado em CGI, eu acho. Eu tentei o seu código acima no Apache2 no modo normal (não no modo CGI) e estava com erro porque $ _SERVER ['arv'] [0] não é um índice. Observe também que tenho o relatório completo de erros do PHP ativado e esses erros foram erros de aviso.
Volomike 17/03/10
Funciona como um encanto, só precisa de um pouco de atualização para evitar erros no parâmetro string de consulta: $query = isset($_SERVER['argv']) ? substr($_SERVER['argv'][0], strpos($_SERVER['argv'][0], ';') + 1) : '';. Atualizei sua resposta para incluir isso.
Zuul
4

REQUEST_URI é definido pelo Apache, portanto você não o obterá com o IIS. Tente fazer um var_dump ou print_r em $ _SERVER e veja quais valores existem lá que você pode usar.

Peter Bailey
fonte
3

A parte pós-título da URL é posterior ao seu index.phparquivo, que é uma maneira comum de fornecer URLs amigáveis ​​sem usar mod_rewrite. O posttitle é, portanto, parte da string de consulta; portanto, você poderá obtê-lo usando $ _SERVER ['QUERY_STRING']

Adam Hopkinson
fonte
2

Use a seguinte linha na parte superior da página PHP onde você está usando $_SERVER['REQUEST_URI']. Isso resolverá seu problema.

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

Oh, a diversão de um trecho!

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;
    }
}

Tem retornos bonitos 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
fonte
0

Todo mundo esqueceu http_build_url ?

http_build_url($_SERVER['REQUEST_URI']);

Quando nenhum parâmetro é passado, http_build_urlele assume automaticamente o URL atual. Eu esperaria REQUEST_URIser incluído também, embora pareça ser necessário para incluir os parâmetros GET.

O exemplo acima retornará URL completo.

Gajus
fonte
1
Isso requer pecl_http.
Omar Abid
@OmarAbid eu recomendo. :-)
Gajus 15/11
Eu entendo sua posição. Mas, ao criar scripts que serão usados ​​em plataformas diferentes das quais você não tem controle, é necessário escolher algo bastante padrão.
Omar Abid
1
Se você estiver construindo uma biblioteca, cabe a você definir os requisitos. A pergunta original não aborda esse cenário. Portanto, faz sentido nomear todas as alternativas.
Gajus
0

Usei o código a seguir e estou obtendo o resultado certo ...

<?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();
?>
Joomla Developers
fonte
Está funcionando bem Se você não possui HTTPS, deseja remover sua linha.
0

No meu servidor apache, isso me dá a URL completa no formato exato que você está procurando:

$_SERVER["SCRIPT_URI"]
Hüseyin Yağlı
fonte
0

Suporte a proxy reverso!

Algo um pouco mais robusto. Nota Funcionará apenas em 5.3ou superior.

/*
 * 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'])), '/'));
}
user1949536
fonte