web-dev-qa-db-fra.com

Comment obtenir l'URL complète de la page en cours sur un serveur Windows/IIS?

J'ai déplacé un WordPress installation dans un nouveau dossier sur un serveur Windows / IIS . J'installe des redirections 301 en PHP, mais cela ne semble pas fonctionner. Les URL de mes messages ont le format suivant:

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

Je n'arrive pas à comprendre comment récupérer la partie /post-title/ de l'URL.

$_SERVER["REQUEST_URI"] - que tout le monde semble recommander - renvoie une chaîne vide. $_SERVER["PHP_SELF"] ne fait que renvoyer index.php. Pourquoi est-ce et comment puis-je le réparer?

137
CtrlDot

Peut-être, parce que vous êtes sous IIS, 

$_SERVER['PATH_INFO']

est ce que vous voulez, en fonction des URL que vous avez utilisées pour expliquer.

Pour Apache, vous utiliseriez $_SERVER['REQUEST_URI'].

135
Vinko Vrsalovic
$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;
63
Tyler Carter

Pour Apache:

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


Vous pouvez également utiliser HTTP_Host au lieu de SERVER_NAME comme l'a commenté Herman. Voir cette question connexe pour une discussion complète. En bref, vous êtes probablement d'accord pour utiliser l'un ou l'autre. Voici la version "Host":

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


Pour les paranoïaques/Pourquoi c'est important

En règle générale, je place ServerName dans VirtualHost parce que je veux que that soit la forme canonical du site Web. Le $_SERVER['HTTP_Host'] est défini en fonction des en-têtes de la demande. Si le serveur répond à tout/tous les noms de domaine à cette adresse IP, un utilisateur pourrait usurper l'en-tête, ou pire encore, quelqu'un pourrait pointer un enregistrement DNS vers votre adresse IP et votre serveur/site Web servirait alors un site Web avec liens construits sur une URL incorrecte. Si vous utilisez cette dernière méthode, vous devez également configurer votre vhost ou configurer une règle .htaccess pour appliquer le domaine que vous souhaitez diffuser, par exemple:

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

J'espère que cela pourra aider. Le véritable intérêt de cette réponse était simplement de fournir la première ligne de code aux personnes qui se sont retrouvées ici en cherchant un moyen d'obtenir l'URL complète avec Apache :)

36
cwd

$_SERVER['REQUEST_URI'] ne fonctionne pas sur IIS, mais j'ai trouvé ceci:  http://neosmart.net/blog/2006/100-Apache-compliant-request_uri-for-iis-and-windows/ ce qui semble prometteur.

11
Greg

Utilisez cette classe pour que l'URL fonctionne.

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;
9
Sureshkumar

Ajouter:

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

Ensuite, appelez simplement la fonction my_url.

7
Avery

J'utilise la fonction suivante pour obtenir l'URL complète actuelle. Cela devrait fonctionner sur IIS et 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;
}
5
Jrgns

REQUEST_URI est défini par Apache, vous ne l'obtiendrez donc pas avec IIS. Essayez de faire un var_dump ou print_r sur $ _SERVER et voyez quelles sont les valeurs utilisables.

4
Peter Bailey

La partie post-titre du URL se trouve après votre fichier index.php, qui est un moyen courant de fournir des URL conviviales sans utiliser mod_rewrite. Le post-titre fait donc réellement partie de la chaîne de requête. Vous devriez donc pouvoir le récupérer avec $ _SERVER ['QUERY_STRING'].

3
Adam Hopkinson

Utilisez la ligne suivante en haut de la page PHP où vous utilisez $_SERVER['REQUEST_URI']. Cela résoudra votre problème.

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

Oh, le plaisir d'un extrait!

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

Il a de beaux retours comme:

// 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/"
//      }
1
SpYk3HH

J'ai utilisé le code suivant et j'obtiens le bon résultat ...

<?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();
?>
0
Joomla Developers

Sur mon serveur Apache, cela me donne l'URL complète au format exact que vous recherchez:

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

Prise en charge du proxy inverse!

Quelque chose d'un peu plus robuste. Note Cela ne fonctionnera que sur 5.3 ou supérieur.

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

Tout le monde a oublié http_build_url ?

http_build_url($_SERVER['REQUEST_URI']);

Quand aucun paramètre n'est passé à http_build_url, l'URL actuelle sera automatiquement assumée. Je m'attendrais à ce que REQUEST_URI soit également inclus, bien que cela semble nécessaire pour inclure les paramètres GET.

L'exemple ci-dessus renverra une URL complète.

0
Gajus