Jak uzyskać pełny adres URL bieżącej strony na serwerze Windows / IIS?


137

Przeniosłem instalację WordPress do nowego folderu na serwerze Windows / IIS . Ustawiam przekierowania 301 w PHP, ale wygląda na to, że nie działa. Adresy URL moich postów mają następujący format:

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

Nie mogę dowiedzieć się, jak pobrać /post-title/część adresu URL.

$_SERVER["REQUEST_URI"]- co wszyscy wydają się zalecać - zwraca pusty ciąg. $_SERVER["PHP_SELF"]właśnie wraca index.php. Dlaczego tak się dzieje i jak mogę to naprawić?


24
Po prostu wykonaj print_r ($ _ SERVER) i zobacz, jakie dane są dla Ciebie dostępne. Jeśli możesz uzyskać pełny adres URL, możesz wywołać pathinfo ($ url), aby uzyskać nazwę pliku.
gradbot

18
Należy zauważyć, że to pytanie dotyczy IIS, a nie PHP w ogóle. W Apache wystarczy użyć $ _SERVER ['REQUEST_URI'].
Michał Tatarynowicz

@Pies Z pewnością $ _SERVER ['REQUEST_URI'] jest drogą do zrobienia ... ale jak mogę pobrać określoną część identyfikatora URI. Na przykład mam ten identyfikator URI: /Appointments/Administrator/events.php/219 ... jak mogę pobrać numer po /events.php/
Dimitris Papageorgiou

Odpowiedzi:


135

Może dlatego, że korzystasz z usług IIS,

$_SERVER['PATH_INFO']

jest tym, czego chcesz, na podstawie adresów URL, których użyłeś do wyjaśnienia.

W przypadku Apache użyłbyś $_SERVER['REQUEST_URI'].


Cześć, używając tego po prostu otrzymuję następujący błąd? Notice: Undefined index: PATH_INFO in /home/tdpk/public_html/system/config.php on line 14
chhameed

6
ups, drat - właśnie sobie uświadomiłem, że to pytanie dotyczy usług IIS i używam. Przepraszamy za głosy przeciw.
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 jasno określony IIS - REQUEST_URI nie jest dostępny w ramach IIS
Tom Auger

1
Nigdy nie powinieneś używać magicznych cytatów, chyba że absolutnie musisz tego robić w php.
Sprawa

2
@TomAuger Musisz spojrzeć na oś czasu. OP dodał to długo po tym, jak odpowiedziałem na pytanie. Oryginalne pytanie zostało zadane około rok przed na nie odpowiedzią.
Tyler Carter

7
@Stan, korzystanie z gier pojedynczych w porównaniu z podwójnymi nie przynosi żadnych korzyści w zakresie wydajności netto. Brak, nadda, zip, zero. To opowieść starej żony z ery PHP3. Proszę, nie wykonuj tak trywialnego zniekształcania treści.
Charles,

36

Apache:

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


Możesz także użyć HTTP_HOSTzamiast, SERVER_NAMEjak skomentował Herman. Zobacz to pokrewne pytanie, aby uzyskać pełną dyskusję. Krótko mówiąc, prawdopodobnie nie masz nic przeciwko korzystaniu z jednego z nich. Oto wersja „hosta”:

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


Dla paranoików / Dlaczego to ma znaczenie

Zwykle ustawiam ServerNamew formacie, VirtualHostponieważ chcę , aby była to kanoniczna forma witryny. $_SERVER['HTTP_HOST']Jest ustawiony na podstawie nagłówków żądań. Jeśli serwer odpowie na jakąkolwiek / wszystkie nazwy domen pod tym adresem IP, użytkownik może sfałszować nagłówek lub, co gorsza, ktoś może wskazać rekord DNS na Twój adres IP, a wtedy Twój serwer / witryna będzie obsługiwać witrynę z dynamicznym linki utworzone na podstawie nieprawidłowego adresu URL. Jeśli korzystasz z tej drugiej metody, powinieneś również skonfigurować vhostlub ustawić .htaccessregułę wymuszającą domenę, którą chcesz obsługiwać, na przykład:

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

Mam nadzieję, że to pomoże. Prawdziwym celem tej odpowiedzi było po prostu podanie pierwszej linii kodu dla tych osób, które znalazły się tutaj, szukając sposobu na uzyskanie pełnego adresu URL za pomocą apache :)


2
Należy użyć $_SERVER['HTTP_HOST']zamiast $_SERVER['SERVER_NAME']. Jeśli istnieje konfiguracja hosta wirtualnego, SERVER_NAME pokaże tę nazwę. Może to być coś takiego, *.example.comco nie jest ważne.
Herman J. Radtke III


9

Użyj tej klasy, aby uzyskać adres 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
czy to nie przesada?
s3v3n

7

Dodaj:

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

Następnie po prostu wywołaj my_urlfunkcję.


5

Używam następującej funkcji, aby uzyskać bieżący, pełny adres URL. To powinno działać w usługach IIS i 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;
}

Myślę, że argv nie zadziała, jeśli nie używasz opartego na CGI Apache lub IIS. Wypróbowałem Twój kod powyżej na Apache2 w trybie zwykłym (nie w trybie CGI) i wystąpił błąd, ponieważ $ _SERVER ['arv'] [0] nie jest indeksem. Zauważ również, że mam włączone pełne raportowanie błędów PHP i te błędy były błędami powiadomień.
Volomike

Działa jak czar, tylko potrzebuje trochę aktualizacji w celu uniknięcia błędów w parametrze ciąg zapytania: $query = isset($_SERVER['argv']) ? substr($_SERVER['argv'][0], strpos($_SERVER['argv'][0], ';') + 1) : '';. Zaktualizowałem twoją odpowiedź, aby to uwzględnić.
Zuul

4

REQUEST_URI jest ustawiane przez Apache, więc nie dostaniesz go z IIS. Spróbuj wykonać var_dump lub print_r na $ _SERVER i zobacz, jakie wartości tam istnieją, których możesz użyć.


3

Część adresu URL zawierająca posttitle znajduje się po index.phppliku, co jest powszechnym sposobem dostarczania przyjaznych adresów URL bez używania mod_rewrite. Dlatego tytuł posta jest w rzeczywistości częścią ciągu zapytania, więc powinieneś być w stanie go pobrać za pomocą $ _SERVER ['QUERY_STRING']


2

Użyj następującego wiersza u góry strony PHP, na której używasz $_SERVER['REQUEST_URI']. To rozwiąże Twój problem.

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

1

Och, zabawa z fragmentu!

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

Ma piękne zwroty, takie jak:

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

Wszyscy zapomnieli http_build_url ?

http_build_url($_SERVER['REQUEST_URI']);

Gdy nie zostaną przekazane żadne parametry http_build_url, automatycznie przyjmie aktualny adres URL. Spodziewałbym REQUEST_URIsię, że zostanie uwzględniony, choć wydaje się, że jest to wymagane w celu uwzględnienia parametrów GET.

Powyższy przykład zwróci pełny adres URL.


1
Wymaga to pecl_http.
Omar Abid,

@OmarAbid Polecam. :-)
Gajus

Rozumiem twoje stanowisko. Ale budując skrypty, które będą używane na różnych platformach, nad którymi nie masz kontroli, musisz wybrać coś całkiem standardowego.
Omar Abid

1
Jeśli tworzysz bibliotekę, to do Ciebie należy określenie wymagań. Oryginalne pytanie w ogóle nie odnosi się do takiego scenariusza. Dlatego warto nazwać wszystkie alternatywy.
Gajus

0

Użyłem następującego kodu i otrzymuję właściwy wynik ...

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

Działa dobrze Jeśli nie masz protokołu HTTPS, chcesz usunąć jego linię.

0

Na moim serwerze Apache otrzymuję pełny adres URL w dokładnym formacie, którego szukasz:

$_SERVER["SCRIPT_URI"]

0

Obsługa Reverse Proxy!

Coś bardziej wytrzymałego. Uwaga To będzie działać tylko na 5.3lub nowszym.

/*
 * 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'])), '/'));
}
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.