Як я можу отримати повну URL-адресу поточної сторінки на сервері Windows / IIS?


137

Я перемістив установку WordPress у нову папку на сервері Windows / IIS . Я встановлюю 301 переадресацію в PHP, але це, здається, не працює. URL-адреси моїх публікацій мають такий формат:

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

Я не можу зрозуміти, як схопити /post-title/частину URL-адреси.

$_SERVER["REQUEST_URI"]- що, начебто, рекомендують усі, - повертає порожню рядок. $_SERVER["PHP_SELF"]просто повертається index.php. Чому це так, і як це можна виправити?


24
Просто зробіть print_r ($ _ SERVER) і подивіться, які дані вам доступні. Якщо ви можете отримати повну URL-адресу, тоді ви можете зателефонувати в довідник ($ url), щоб отримати ім'я файлу.
gradbot

18
Слід зазначити, що це питання стосується IIS, а не PHP взагалі. Під Apache ви просто використовуєте $ _SERVER ['REQUEST_URI'].
Michał Tatarynowicz

@Pies Безумовно, $ _SERVER ['REQUEST_URI'] - це спосіб пройти ... але як я можу схопити певну частину URI. Наприклад, у мене є цей URI: /Appointments/Administrator/events.php/219 ... як я можу схопити номер після /events.php/
Димитріс

Відповіді:


135

Можливо, тому, що ви під IIS,

$_SERVER['PATH_INFO']

це те, що ви хочете, на основі URL-адрес, які ви використовували для пояснення.

Для Apache ви б використовували $_SERVER['REQUEST_URI'].


привіт, використовуючи це, я просто отримую таку помилку? Notice: Undefined index: PATH_INFO in /home/tdpk/public_html/system/config.php on line 14
chhameed

6
oops, drat - щойно зрозумів, що це питання стосується IIS, і я використовую. Вибачте за скарга.
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
ОП чітко зазначено IIS - REQUEST_URI не доступний під IIS
Том Оже

1
Ніколи не слід використовувати магічні котирування, якщо ви абсолютно не повинні в php.
Справа

2
@TomAuger Потрібно подивитися на часову шкалу. ОП додав це ще довго після того, як я відповів на запитання. Первісне запитання було задано приблизно за рік до того, як я відповів на нього.
Тайлер Картер

7
@Stan, немає користі від чистої продуктивності від використання синглів для парних пар. Ні, nadda, zip, zero. Це стара казка дружин з епохи PHP3. Будь ласка, не виконуйте такого тривіального керування вмістом.
Чарльз

36

Для Apache:

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


Ви також можете використовувати HTTP_HOSTзамість того, SERVER_NAMEяк прокоментував Герман. Дивіться це пов'язане питання для повного обговорення. Коротше кажучи, ви, мабуть, добре з використанням будь-якого. Ось "хост" версія:

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


Для параноїда / Чому це має значення

Як правило, я встановлюю ServerNameв VirtualHostтому що я хочу , щоб бути канонічною формою на сайті. $_SERVER['HTTP_HOST']Встановлюється на основі заголовків запиту. Якщо сервер відповідає на будь-які / всі доменні імена за цією IP-адресою, користувач може підробити заголовок, або ще гірше, хтось може вказати запис DNS на вашу IP-адресу, і тоді ваш сервер / веб-сайт буде динамічно розміщувати веб-сайт посилання, побудовані на неправильній URL-адресі. Якщо ви використовуєте останній метод, ви також повинні налаштувати своє vhostабо налаштувати .htaccessправило для виконання домену, який ви хочете обслуговувати, щось на зразок:

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

Сподіваюся, що це допомагає. Справжній сенс цієї відповіді полягав лише в тому, щоб надати перший рядок коду тим людям, які потрапили сюди під час пошуку способу отримати повну URL-адресу за допомогою апачі :)


2
Це слід використовувати $_SERVER['HTTP_HOST']замість $_SERVER['SERVER_NAME']. Якщо є налаштування віртуального хоста, тоді SERVER_NAME покаже це ім'я. Це може бути щось таке, *.example.comщо не вірно.
Герман Й. Радтке III


9

Використовуйте цей клас для отримання 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
це не трохи зайвого?
s3v3n

7

Додати:

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

Тоді просто викличте my_urlфункцію.


5

Я використовую наступну функцію, щоб отримати поточну повну URL-адресу. Це повинно працювати над IIS та 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 не працюватиме, якщо ви не використовуєте Apache на базі CGI або IIS, я думаю. Я спробував ваш код вище на Apache2 у звичайному режимі (не у режимі CGI) і помилявся, оскільки $ _SERVER ['arv'] [0] не є індексом. Зауважте також, що у мене включено повне повідомлення про помилки PHP, і ці помилки були помилками сповіщення.
Воломійка

Працює як шарм, просто потрібно трохи поновлення , щоб запобігти помилкам в параметрі рядка запиту: $query = isset($_SERVER['argv']) ? substr($_SERVER['argv'][0], strpos($_SERVER['argv'][0], ';') + 1) : '';. Я оновив вашу відповідь, щоб включити її.
Зуул

4

REQUEST_URI встановлюється Apache, тому ви не отримаєте його з IIS. Спробуйте зробити var_dump або print_r на $ _SERVER і подивіться, які значення існують там, які ви можете використовувати.


3

Заголовок частини URL-адреси знаходиться після вашого index.phpфайлу, що є поширеним способом надання дружних URL-адрес без використання mod_rewrite. Отже, заголовок фактично є частиною рядка запиту, тому ви можете отримати його за допомогою $ _SERVER ['QUERY_STRING']


2

Використовуйте наступний рядок у верхній частині сторінки PHP, де ви використовуєте $_SERVER['REQUEST_URI']. Це вирішить вашу проблему.

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

1

О, веселощі з фрагмента!

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

Він має прекрасні прибутки, як:

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

Усі забули http_build_url ?

http_build_url($_SERVER['REQUEST_URI']);

Якщо не передані параметри, http_build_urlвін автоматично припускає поточну URL-адресу. Я також очікував REQUEST_URIби бути включеним, хоча, мабуть, це потрібно для включення параметрів GET.

Наведений вище приклад поверне повну URL-адресу.


1
Для цього потрібен pecl_http.
Омар Абід

@OmarAbid рекомендую. :-)
Гаджус

Я розумію вашу позицію. Але, будуючи сценарії, які будуть використовуватися на різних платформах, якими ви не маєте контролю, вам потрібно вибрати щось досить стандартне.
Омар Абід

1
Якщо ви будуєте бібліотеку, вам належить визначити вимоги. Первісне питання взагалі не стосується такого сценарію. Тому має сенс назвати всі альтернативи.
Гаджус

0

Я використав наступний код, і я отримую правильний результат ...

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

Це добре, якщо у вас немає HTTPS, тоді ви хочете видалити його.

0

На моєму сервері apache це дає мені повну URL-адресу в точному форматі, який ви шукаєте:

$_SERVER["SCRIPT_URI"]

0

Підтримка зворотного проксі!

Щось трохи міцніше. Примітка. Вона працюватиме лише на 5.3або більше.

/*
 * 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'])), '/'));
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.