Wie kann ich die vollständige URL der aktuellen Seite auf einem Windows / IIS-Server abrufen?

137

Ich habe eine WordPress- Installation in einen neuen Ordner auf einem Windows / IIS- Server verschoben . Ich richte 301 Weiterleitungen in PHP ein, aber es scheint nicht zu funktionieren. Meine Post-URLs haben das folgende Format:

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

Ich kann nicht herausfinden, wie ich den /post-title/Teil der URL abrufen kann.

$_SERVER["REQUEST_URI"]- was jeder zu empfehlen scheint - gibt eine leere Zeichenfolge zurück. $_SERVER["PHP_SELF"]kommt gerade zurück index.php. Warum ist das so und wie kann ich es beheben?

CtrlDot
quelle
24
Machen Sie einfach einen print_r ($ _ SERVER) und sehen Sie, welche Daten Ihnen zur Verfügung stehen. Wenn Sie die vollständige URL erhalten können, können Sie pathinfo ($ url) aufrufen, um den Dateinamen abzurufen.
Gradbot
18
Es ist zu beachten, dass es sich bei dieser Frage um IIS handelt, nicht um PHP im Allgemeinen. Unter Apache verwenden Sie einfach $ _SERVER ['REQUEST_URI'].
Michał Tatarynowicz
@Pies Natürlich ist $ _SERVER ['REQUEST_URI'] der richtige Weg ... aber wie ich einen bestimmten Teil der URI abrufen kann. Zum Beispiel habe ich diese URI: /Appointments/Administrator/events.php/219 ... wie ich die Nummer nach /events.php/
Dimitris Papageorgiou
Mögliches Duplikat von Holen Sie sich die vollständige URL in PHP
T.Todua

Antworten:

135

Vielleicht, weil Sie unter IIS sind,

$_SERVER['PATH_INFO']

ist das, was Sie wollen, basierend auf den URLs, die Sie zur Erklärung verwendet haben.

Für Apache würden Sie verwenden $_SERVER['REQUEST_URI'].

Vinko Vrsalovic
quelle
Hallo, wenn ich das benutze, erhalte ich nur den folgenden Fehler? Notice: Undefined index: PATH_INFO in /home/tdpk/public_html/system/config.php on line 14
Chhameed
6
oops, drat - habe gerade festgestellt, dass es sich bei dieser Frage um IIS handelt, und ich verwende. Entschuldigung für die Ablehnung.
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
quelle
11
OP klar angegeben IIS - REQUEST_URI ist nicht verfügbar unter IIS
Tom Auger
1
Sie sollten niemals magische Zitate verwenden, es sei denn, Sie müssen unbedingt in PHP.
Fall
2
@ TomAuger Sie müssen sich die Zeitleiste ansehen. Das OP fügte dies hinzu, lange nachdem ich die Frage beantwortet hatte. Die ursprüngliche Frage wurde ungefähr ein Jahr vor meiner Beantwortung gestellt.
Tyler Carter
7
@Stan, es gibt keinen Netto-Leistungsvorteil bei der Verwendung von Singles gegenüber Doubles. Keine, Nadda, Zip, Null. Es ist eine Geschichte einer alten Frau aus der PHP3-Ära. Bitte führen Sie keine so trivialen Mangeln an Inhalten durch.
Charles
36

Für Apache:

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


Sie können auch HTTP_HOSTanstelle von SERVER_NAMEwie Herman kommentiert verwenden. In dieser verwandten Frage finden Sie eine vollständige Diskussion. Kurz gesagt, Sie sind wahrscheinlich damit einverstanden, beides zu verwenden. Hier ist die 'Host'-Version:

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


Für die Paranoiden / Warum es wichtig ist

Normalerweise setze ich ServerNamein, VirtualHostweil ich möchte, dass dies die kanonische Form der Website ist. Das $_SERVER['HTTP_HOST']wird basierend auf den Anforderungsheadern festgelegt. Wenn der Server auf einen oder alle Domainnamen unter dieser IP-Adresse antwortet, könnte ein Benutzer den Header fälschen, oder schlimmer noch, jemand könnte einen DNS-Eintrag auf Ihre IP-Adresse verweisen, und dann würde Ihr Server / Ihre Website eine Website mit Dynamik bereitstellen Links, die auf einer falschen URL basieren. Wenn Sie die letztere Methode verwenden, sollten Sie auch Ihre konfigurieren vhostoder eine .htaccessRegel einrichten , um die Domain zu erzwingen, die Sie bereitstellen möchten.

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

Hoffentlich hilft das. Der eigentliche Sinn dieser Antwort bestand darin, die erste Codezeile für diejenigen Personen bereitzustellen, die hier gelandet sind, als sie nach einer Möglichkeit gesucht haben, die vollständige URL mit Apache zu erhalten :)

cwd
quelle
2
Dies sollte $_SERVER['HTTP_HOST']anstelle von verwenden $_SERVER['SERVER_NAME']. Wenn ein virtueller Host eingerichtet ist, zeigt SERVER_NAME diesen Namen an. Es kann so etwas wie *.example.comdas sein, was nicht gültig ist.
Herman J. Radtke III
9

Verwenden Sie diese Klasse, damit die URL funktioniert.

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
quelle
10
Ist das nicht ein bisschen übertrieben?
s3v3n
7

Hinzufügen:

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

Dann rufen Sie einfach die my_urlFunktion auf.

Avery
quelle
5

Ich benutze die folgende Funktion, um die aktuelle, vollständige URL zu erhalten. Dies sollte unter IIS und Apache funktionieren.

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
quelle
argv funktioniert nicht, wenn Sie keinen CGI-basierten Apache oder IIS verwenden, denke ich. Ich habe Ihren Code oben auf Apache2 im regulären Modus (nicht im CGI-Modus) ausprobiert und habe einen Fehler gemacht, weil $ _SERVER ['arv'] [0] kein Index ist. Beachten Sie auch, dass ich die vollständige PHP-Fehlerberichterstattung aktiviert habe und diese Fehler Benachrichtigungsfehler waren.
Volomike
Funktioniert wie ein Zauber, benötigt nur ein kleines Update, um Fehler im Parameter der Abfragezeichenfolge zu vermeiden : $query = isset($_SERVER['argv']) ? substr($_SERVER['argv'][0], strpos($_SERVER['argv'][0], ';') + 1) : '';. Ich habe Ihre Antwort aktualisiert, um dies aufzunehmen.
Zuul
4

REQUEST_URI wird von Apache festgelegt, sodass Sie es mit IIS nicht erhalten. Versuchen Sie, einen var_dump oder print_r für $ _SERVER auszuführen, und sehen Sie, welche Werte dort vorhanden sind, die Sie verwenden können.

Peter Bailey
quelle
3

Der Posttitle-Teil der URL befindet sich hinter Ihrer index.phpDatei. Dies ist eine übliche Methode, um benutzerfreundliche URLs ohne Verwendung von mod_rewrite bereitzustellen. Der Posttitel ist daher tatsächlich Teil der Abfragezeichenfolge, daher sollten Sie ihn mit $ _SERVER ['QUERY_STRING'] abrufen können.

Adam Hopkinson
quelle
2

Verwenden Sie die folgende Zeile oben auf der PHP-Seite, auf der Sie sie verwenden $_SERVER['REQUEST_URI']. Dadurch wird Ihr Problem behoben.

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

Oh, der Spaß eines Schnipsels!

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

Es hat schöne Renditen wie:

// 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
quelle
0

Jeder hat http_build_url vergessen ?

http_build_url($_SERVER['REQUEST_URI']);

Wenn keine Parameter übergeben werden, http_build_urlwird automatisch die aktuelle URL angenommen. Ich würde erwarten REQUEST_URI, auch aufgenommen zu werden, obwohl es erforderlich zu sein scheint, um die GET-Parameter aufzunehmen.

Das obige Beispiel gibt die vollständige URL zurück.

Gajus
quelle
1
Dies erfordert pecl_http.
Omar Abid
@OmarAbid Ich empfehle es. :-)
Gajus
Ich verstehe deine Position. Wenn Sie jedoch Skripte erstellen, die auf verschiedenen Plattformen verwendet werden sollen, auf die Sie keinen Einfluss haben, müssen Sie einen Standard auswählen.
Omar Abid
1
Wenn Sie eine Bibliothek erstellen, müssen Sie die Anforderungen definieren. Die ursprüngliche Frage behandelt ein solches Szenario überhaupt nicht. Daher ist es sinnvoll, alle Alternativen zu benennen.
Gajus
0

Ich habe den folgenden Code verwendet und erhalte das richtige Ergebnis ...

<?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-Entwickler
quelle
Es funktioniert gut Wenn Sie kein HTTPS haben, möchten Sie die Zeile entfernen.
0

Auf meinem Apache-Server gibt mir dies die vollständige URL in genau dem Format, das Sie suchen:

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

Reverse Proxy Support!

Etwas etwas robusteres. Hinweis Es funktioniert nur bei 5.3oder höher.

/*
 * 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
quelle