Làm cách nào tôi có thể nhận URL đầy đủ của trang hiện tại trên máy chủ Windows / IIS?


137

Tôi đã chuyển một cài đặt WordPress sang một thư mục mới trên máy chủ Windows / IIS . Tôi đang thiết lập 301 chuyển hướng trong PHP, nhưng dường như nó không hoạt động. URL bài đăng của tôi có định dạng sau:

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

Tôi không thể tìm ra cách lấy /post-title/một phần của URL.

$_SERVER["REQUEST_URI"]- điều mà mọi người dường như khuyên dùng - đang trả về một chuỗi trống. $_SERVER["PHP_SELF"]chỉ là trở về index.php. Tại sao điều này, và làm thế nào tôi có thể sửa chữa nó?


24
Chỉ cần thực hiện print_r ($ _ SERVER) và xem dữ liệu nào có sẵn cho bạn. Nếu bạn có thể nhận được URL đầy đủ thì bạn có thể gọi pathinfo ($ url) để lấy tên tệp.
gradbot

18
Cần lưu ý rằng câu hỏi này là về IIS, không phải PHP nói chung. Trong Apache, bạn chỉ cần sử dụng $ _SERVER ['REQUEST_URI'].
Michał Tatarynowicz

@Pies Chắc chắn $ _SERVER ['REQUEST_URI'] là cách để đi ... nhưng làm thế nào tôi có thể lấy một phần cụ thể của URI. Ví dụ: tôi có URI này: /Appointments/Admaster/events.php/219 ... làm thế nào tôi có thể lấy số sau /events.php/
Dimitris Papageorgiou

có thể trùng lặp với Nhận URL đầy đủ trong PHP
T.Todua

Câu trả lời:


135

Có lẽ, vì bạn đang ở trong IIS,

$_SERVER['PATH_INFO']

là những gì bạn muốn, dựa trên các URL bạn đã sử dụng để giải thích.

Đối với Apache, bạn sẽ sử dụng $_SERVER['REQUEST_URI'].


chào bằng cách sử dụng này tôi chỉ nhận được lỗi sau? Notice: Undefined index: PATH_INFO in /home/tdpk/public_html/system/config.php on line 14
chhame

6
Rất tiếc, drat - vừa nhận ra câu hỏi này là về IIS và tôi đang sử dụng. Xin lỗi cho downvote.
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 đã nêu rõ IIS - REQUEST_URI không khả dụng trong IIS
Tom Auger

1
Bạn không bao giờ nên sử dụng Magicquote trừ khi bạn hoàn toàn phải có trong php.
Trường hợp

2
@TomAuger Bạn cần xem dòng thời gian. OP đã thêm điều này rất lâu sau khi tôi trả lời câu hỏi. Câu hỏi ban đầu đã được hỏi khoảng một năm trước khi tôi trả lời nó.
Tyler Carter

7
@Stan, không có lợi ích hiệu suất ròng bằng không khi sử dụng đơn trên đôi. Không, nadda, zip, zero. Đó là một câu chuyện về wive cũ từ thời PHP3. Xin vui lòng không thực hiện xáo trộn tầm thường như vậy đến nội dung.
Charles

36

Đối với Apache:

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


Bạn cũng có thể sử dụng HTTP_HOSTthay vì SERVER_NAMEnhư Herman nhận xét. Xem câu hỏi liên quan này để thảo luận đầy đủ. Nói tóm lại, bạn có thể ổn với việc sử dụng một trong hai. Đây là phiên bản 'máy chủ':

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


Đối với người hoang tưởng / Tại sao nó có vấn đề

Thông thường, tôi đặt ServerNametrong VirtualHostvì tôi muốn đó là hình thức chính tắc của trang web. Các $_SERVER['HTTP_HOST']được thiết lập dựa trên các tiêu đề yêu cầu. Nếu máy chủ phản hồi bất kỳ / tất cả các tên miền tại địa chỉ IP đó, người dùng có thể giả mạo tiêu đề hoặc tệ hơn, ai đó có thể trỏ bản ghi DNS đến địa chỉ IP của bạn và sau đó máy chủ / trang web của bạn sẽ cung cấp một trang web động liên kết được xây dựng trên một URL không chính xác. Nếu bạn sử dụng phương thức sau, bạn cũng nên định cấu hình vhosthoặc thiết lập .htaccessquy tắc để thực thi tên miền bạn muốn phân phát, đại loại như:

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

Mong rằng sẽ giúp. Điểm thực sự của câu trả lời này chỉ là cung cấp dòng mã đầu tiên cho những người đã kết thúc ở đây khi tìm kiếm cách để có được URL hoàn chỉnh với apache :)


2
Điều này nên sử dụng $_SERVER['HTTP_HOST']thay vì $_SERVER['SERVER_NAME']. Nếu có thiết lập máy chủ ảo, thì SERVER_NAME sẽ hiển thị tên đó. Nó có thể là một cái gì đó như *.example.comkhông hợp lệ.
Herman J. Radtke III


9

Sử dụng lớp này để có được URL hoạt động.

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
Đây không phải là một chút quá mức?
s3v3n

7

Thêm vào:

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

Sau đó chỉ cần gọi my_urlhàm.


5

Tôi sử dụng chức năng sau để có được URL đầy đủ hiện tại. Điều này sẽ hoạt động trên IIS và 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 sẽ không hoạt động nếu bạn không sử dụng Apache hoặc IIS dựa trên CGI, tôi nghĩ vậy. Tôi đã thử mã của bạn ở trên trên Apache2 ở chế độ thông thường (không phải chế độ CGI) và đã bị lỗi vì $ _SERVER ['arv'] [0] không phải là một chỉ mục. Cũng lưu ý rằng tôi đã bật báo cáo lỗi PHP đầy đủ và các lỗi này là lỗi thông báo.
Volomike 17/03/2016

Hoạt động như một bùa mê, chỉ cần một bản cập nhật nhỏ để ngăn lỗi trên tham số chuỗi truy vấn : $query = isset($_SERVER['argv']) ? substr($_SERVER['argv'][0], strpos($_SERVER['argv'][0], ';') + 1) : '';. Tôi đã cập nhật câu trả lời của bạn để bao gồm điều này.
Zuul

4

REQUEST_URI được thiết lập bởi Apache, vì vậy bạn sẽ không nhận được nó bằng IIS. Hãy thử thực hiện var_dump hoặc print_r trên $ _SERVER và xem những giá trị nào tồn tại ở đó mà bạn có thể sử dụng.


3

Phần tiêu đề của URL nằm sau index.phptệp của bạn , đây là cách phổ biến để cung cấp các URL thân thiện mà không cần sử dụng mod_rewrite. Do đó, tiêu đề thực sự là một phần của chuỗi truy vấn, vì vậy bạn sẽ có thể lấy nó bằng cách sử dụng $ _SERVER ['QUERY_STRING']


2

Sử dụng dòng sau trên đầu trang PHP nơi bạn đang sử dụng $_SERVER['REQUEST_URI']. Điều này sẽ giải quyết vấn đề của bạn.

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

1

Ôi, niềm vui của một đoạn trích!

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

Nó có lợi nhuận đẹp như:

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

Mọi người quên http_build_url ?

http_build_url($_SERVER['REQUEST_URI']);

Khi không có tham số nào được chuyển đến http_build_urlnó sẽ tự động giả sử URL hiện tại. Tôi cũng mong đợi REQUEST_URIđược bao gồm, mặc dù nó dường như được yêu cầu để bao gồm các tham số GET.

Ví dụ trên sẽ trả về URL đầy đủ.


1
Điều này đòi hỏi pecl_http.
Omar Abid

@OmarAdid Tôi khuyên bạn nên dùng nó. :-)
Gajus

Tôi hiểu vị trí của bạn. Nhưng khi xây dựng các tập lệnh sẽ được sử dụng trong các nền tảng khác nhau mà bạn không có quyền kiểm soát, bạn cần chọn một cái gì đó khá chuẩn.
Omar Abid

1
Nếu bạn đang xây dựng một thư viện, bạn cần xác định các yêu cầu. Câu hỏi ban đầu không đề cập đến kịch bản như vậy cả. Do đó, nó có ý nghĩa để đặt tên cho tất cả các lựa chọn thay thế.
Gajus

0

Tôi đã sử dụng mã sau đây và tôi nhận được kết quả đúng ...

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

Nó hoạt động tốt Nếu bạn không có HTTPS thì bạn muốn xóa dòng đó.

0

Trong máy chủ apache của tôi, điều này cung cấp cho tôi URL đầy đủ ở định dạng chính xác mà bạn đang tìm kiếm:

$_SERVER["SCRIPT_URI"]

0

Hỗ trợ Proxy ngược!

Một cái gì đó mạnh mẽ hơn một chút. Lưu ý Nó sẽ chỉ hoạt động trên 5.3hoặc lớn hơn.

/*
 * 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'])), '/'));
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.