Comment puis-je obtenir l'URL complète de la page actuelle sur un serveur Windows / IIS?


137

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

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

Je ne peux pas comprendre comment saisir la /post-title/partie de l'URL.

$_SERVER["REQUEST_URI"]- ce que tout le monde semble recommander - renvoie une chaîne vide. $_SERVER["PHP_SELF"]est juste de retour index.php. Pourquoi cela et comment puis-je y remédier?


24
Faites simplement un print_r ($ _ SERVER) et voyez quelles données vous sont disponibles. Si vous pouvez obtenir l'URL complète, vous pouvez appeler pathinfo ($ url) pour obtenir le nom du fichier.
gradbot

18
Il convient de noter que cette question concerne IIS, pas PHP en général. Sous Apache, vous utiliseriez simplement $ _SERVER ['REQUEST_URI'].
Michał Tatarynowicz

@Pies Certainement $ _SERVER ['REQUEST_URI'] est la voie à suivre ... mais comment je peux récupérer une partie spécifique de l'URI.Par exemple, j'ai cet URI: /Appointments/Administrator/events.php/219 ... comment je peux saisir le numéro après /events.php/
Dimitris Papageorgiou

duplication possible de Obtenir l'URL complète en PHP
T.Todua

Réponses:


135

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


salut en utilisant cela, je viens de recevoir l'erreur suivante? Notice: Undefined index: PATH_INFO in /home/tdpk/public_html/system/config.php on line 14
chhameed

6
oups, drat - je viens de réaliser que cette question concerne IIS, et j'utilise. Désolé pour le vote défavorable.
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 clairement indiqué IIS - REQUEST_URI n'est pas disponible sous IIS
Tom Auger

1
Vous ne devriez jamais utiliser magicquotes sauf si vous devez absolument le faire en php.
Affaire du

2
@TomAuger Vous devez regarder la chronologie. Le PO a ajouté cela longtemps après avoir répondu à la question. La question initiale a été posée environ un an avant d'y répondre.
Tyler Carter

7
@Stan, il n'y a aucun avantage net en termes de performances à utiliser des simples plutôt que des doubles. Aucun, nadda, zip, zéro. C'est une vieille histoire d'épouse de l'ère PHP3. S'il vous plaît, n'effectuez pas une modification aussi triviale du contenu.
Charles

36

Pour Apache:

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


Vous pouvez également utiliser HTTP_HOSTau lieu de SERVER_NAMEcomme 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 'hôte':

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


Pour le paranoïaque / Pourquoi c'est important

En règle générale, je mets ServerNamele VirtualHostcar je veux que ce soit la forme canonique du site Web. Le $_SERVER['HTTP_HOST']est défini en fonction des en-têtes de demande. Si le serveur répond à l'un / tous les noms de domaine à cette adresse IP, un utilisateur pourrait usurper l'en-tête, ou pire, quelqu'un pourrait pointer un enregistrement DNS vers votre adresse IP, puis votre serveur / site Web servirait un site Web dynamique. liens construits sur une URL incorrecte. Si vous utilisez cette dernière méthode, vous devez également configurer votre vhostou mettre en place une .htaccessrègle pour appliquer le domaine que vous souhaitez diffuser, quelque chose comme:

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 vrai point de cette réponse était simplement de fournir la première ligne de code pour les personnes qui se sont retrouvées ici lors de la recherche d'un moyen d'obtenir l'URL complète avec apache :)


2
Cela devrait utiliser à la $_SERVER['HTTP_HOST']place de $_SERVER['SERVER_NAME']. S'il existe une configuration d'hôte virtuel, SERVER_NAME affichera ce nom. Cela peut être quelque chose comme *.example.comqui n'est pas valide.
Herman J. Radtke III


9

Utilisez cette classe pour faire fonctionner l'URL.

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
n'est-ce pas un peu exagéré?
s3v3n

7

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 my_urlfonction.


5

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

argv ne fonctionnera pas si vous n'utilisez pas Apache ou IIS basé sur CGI, je pense. J'ai essayé votre code ci-dessus sur Apache2 en mode normal (pas en mode CGI) et je me suis trompé car $ _SERVER ['arv'] [0] n'est pas un index. Notez également que j'ai activé le rapport d'erreur PHP complet et que ces erreurs étaient des erreurs de notification.
Volomike du

Fonctionne comme un charme, a juste besoin d' une petite mise à jour pour éviter les erreurs sur le paramètre de chaîne de requête: $query = isset($_SERVER['argv']) ? substr($_SERVER['argv'][0], strpos($_SERVER['argv'][0], ';') + 1) : '';. J'ai mis à jour votre réponse pour l'inclure.
Zuul

4

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 valeurs existent là-bas que vous pouvez utiliser.


3

La partie post-titre de l' URL se trouve après votre index.phpfichier, ce qui est un moyen courant de fournir des URL conviviales sans utiliser mod_rewrite. Le titre du post fait donc partie de la chaîne de requête, vous devriez donc pouvoir l'obtenir en utilisant $ _SERVER ['QUERY_STRING']


2

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

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

1

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

0

Tout le monde a oublié http_build_url ?

http_build_url($_SERVER['REQUEST_URI']);

Lorsqu'aucun paramètre n'est passé, http_build_urlil prendra automatiquement l'URL actuelle. Je m'attends REQUEST_URIà être également inclus, bien que cela semble être nécessaire pour inclure les paramètres GET.

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


1
Cela nécessite pecl_http.
Omar Abid

@OmarAbid je le recommande. :-)
Gajus

Je comprends votre position. Mais lorsque vous créez des scripts qui seront utilisés sur différentes plates-formes sur lesquelles vous n'avez pas de contrôle, vous devez choisir quelque chose d'assez standard.
Omar Abid

1
Si vous construisez une bibliothèque, c'est à vous de définir les exigences. La question initiale ne traite pas du tout de ce scénario. Par conséquent, il est logique de nommer toutes les alternatives.
Gajus

0

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

Cela fonctionne bien Si vous n'avez pas de HTTPS, vous souhaitez supprimer sa ligne.

0

Dans mon serveur Apache, cela me donne l'URL complète dans le format exact que vous recherchez:

$_SERVER["SCRIPT_URI"]

0

Prise en charge du proxy inverse!

Quelque chose d'un peu plus robuste. Remarque Cela ne fonctionnera que sur 5.3ou plus.

/*
 * 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'])), '/'));
}
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.