如何在Windows / IIS服务器上获取当前页面的完整URL?


137

我将WordPress安装移至Windows / IIS服务器上的新文件夹。我正在PHP中设置301重定向,但似乎无法正常工作。我的帖子网址具有以下格式:

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,则可以调用pathinfo($ url)获取文件名。
Gradbot

18
应该注意的是,这个问题是关于IIS的,而不是一般的PHP。在Apache下,您只需使用$ _SERVER ['REQUEST_URI']。
2009年

@Pies当然$ _SERVER ['REQUEST_URI']是要走的路...但是我如何获取URI的特定部分。例如,我有以下URI:/Appointments/Administrator/events.php/219 ...我如何在/events.php/之后获取号码
Dimitris Papageorgiou

Answers:


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
2011年

6
糟糕,小子-刚意识到这个问题是关于IIS的,我正在使用。对不起,不好意思。
贾森小号

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明确声明IIS-REQUEST_URI在IIS下不可用
Tom Auger

1
除非绝对必须使用php,否则永远不要使用magicquotes。
案例

2
@TomAuger您需要查看时间轴。在我回答了问题很久之后,OP就添加了这一内容。最初的问题是在我回答问题大约一年之前提出的。
泰勒·卡特

7
@Stan,使用单打而不是双打的净性能收益为零。无,nadda,zip,零。这是PHP3时代的老妇人的故事。请不要对内容进行这种琐碎的处理。
查尔斯

36

对于Apache:

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


您也可以HTTP_HOST代替SERVER_NAMEHerman所说的使用。有关完整讨论,请参见此相关问题。简而言之,您可能都可以使用其中任何一个。这是“主机”版本:

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


对于偏执狂/为什么重要

通常,我设置为ServerName,是VirtualHost因为我希望成为网站的规范形式。该$_SERVER['HTTP_HOST']基于请求头设置。如果服务器响应该IP地址上的任何/所有域名,则用户可能会欺骗标头,或者更糟的是,有人可能将DNS记录指向您的IP地址,然后您的服务器/网站将通过动态方式为网站提供服务建立在错误网址上的链接。如果您使用后一种方法,则还应该配置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

希望有帮助。这个答案的真正目的只是为那些在这里寻找用apache获取完整URL的人的代码提供第一行:)


2
应该使用$_SERVER['HTTP_HOST']代替$_SERVER['SERVER_NAME']。如果存在虚拟主机设置,则SERVER_NAME将显示该名称。可能*.example.com是无效的。
2013年


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
这是不是有点矫over过正?
s3v3n 2012年

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

我认为,如果您未使用基于CGI的Apache或IIS,则argv将无法工作。我在上面的Apache2上以常规模式(不是CGI模式)尝试了您的代码,并且由于$ _SERVER ['arv'] [0]不是索引而出错了。还要注意,我已经打开了完整的PHP错误报告,这些错误是通知错误。
Volomike 2010年

就像超级按钮一样工作,只需稍作更新即可防止查询字符串参数发生错误$query = isset($_SERVER['argv']) ? substr($_SERVER['argv'][0], strpos($_SERVER['argv'][0], ';') + 1) : '';。我已更新您的答案以包括此内容。
Zuul 2013年

4

REQUEST_URI由Apache设置,因此您将无法通过IIS获得它。尝试在$ _SERVER上执行var_dump或print_r,然后查看可以使用的值。


3

在的posttitle部分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我推荐它。:-)
Gajus

我了解你的立场。但是,当构建将在您无法控制的不同平台上使用的脚本时,您需要选择一些非常标准的东西。
奥马尔·阿比德

1
如果要构建库,则由您来定义需求。原始问题根本没有解决这种情况。因此,命名所有替代方案都是有意义的。
Gajus 2013年

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'])), '/'));
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.