【问题标题】:How can I get the current page's full URL on a Windows/IIS server?如何在 Windows/IIS 服务器上获取当前页面的完整 URL?
【发布时间】:2010-09-16 09:21:24
【问题描述】:

我将 WordPress 安装移动到 Windows/IIS 服务器上的新文件夹中。我在 PHP 中设置了 301 重定向,但它似乎不起作用。我的帖子 URL 具有以下格式:

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

我不知道如何获取 URL 的 /post-title/ 部分。

$_SERVER["REQUEST_URI"] - 每个人似乎都推荐 - 返回一个空字符串。 $_SERVER["PHP_SELF"] 只是返回 index.php。为什么会这样,我该如何解决?

【问题讨论】:

  • 只需执行 print_r($_SERVER) 并查看您可以使用哪些数据。如果你能得到完整的 URL,那么你可以调用 pathinfo($url) 来获取文件名。
  • 应该注意,这个问题是关于 IIS 的,而不是一般的 PHP。在 Apache 下,您只需使用 $_SERVER['REQUEST_URI']。
  • @Pies 当然 $_SERVER['REQUEST_URI'] 是要走的路...但是我如何获取 URI 的特定部分。例如我有这个 URI:/Appointments/Administrator/ events.php/219 ...我如何在 /events.php/ 之后获取数字
  • Get the full URL in PHP的可能重复

标签: php iis


【解决方案1】:

也许,因为你在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
  • 哎呀,废话——刚刚意识到这个问题是关于 IIS 的,我正在使用。很抱歉投了反对票。
【解决方案2】:
$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;

【讨论】:

  • OP 明确说明 IIS - REQUEST_URI 在 IIS 下不可用
  • 你不应该使用magicquotes,除非你必须在php中使用。
  • @TomAuger 您需要查看时间线。在我回答了这个问题很久之后,OP 添加了这个。最初的问题是在我回答之前大约一年提出的。
  • @Stan,使用单打胜过双打的净性能优势为零。无,nadda,zip,零。这是 PHP3 时代的老太太的故事。请不要对内容进行如此琐碎的修改。
【解决方案3】:

对于 Apache:

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


正如 Herman 所说,您也可以使用 HTTP_HOST 而不是 SERVER_NAME。有关完整讨论,请参阅this related question。简而言之,您可能都可以使用其中任何一个。这是“主机”版本:

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


偏执狂/为什么重要

通常,我在VirtualHost 中设置ServerName,因为我希望that 成为网站的canonical 形式。 $_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

希望对您有所帮助。这个答案的真正意义只是为那些在寻找使用 apache 获取完整 URL 的方法时最终来到这里的人提供第一行代码:)

【讨论】:

  • 这应该使用$_SERVER['HTTP_HOST'] 而不是$_SERVER['SERVER_NAME']。如果有虚拟主机设置,则 SERVER_NAME 将显示该名称。它可能类似于 *.example.com 是无效的。
【解决方案4】:

$_SERVER['REQUEST_URI'] 在 IIS 上不起作用,但我确实发现了这个:http://neosmart.net/blog/2006/100-apache-compliant-request_uri-for-iis-and-windows/,这听起来很有希望。

【讨论】:

    【解决方案5】:

    使用这个类来获取 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;
    

    【讨论】:

    • 这不是有点矫枉过正吗?
    【解决方案6】:

    添加:

    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 函数。

    【讨论】:

      【解决方案7】:

      我使用以下函数来获取当前的完整 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 错误报告,这些错误是通知错误。
      • 就像一个魅力,只需要一点更新,以防止查询字符串参数错误:$query = isset($_SERVER['argv']) ? substr($_SERVER['argv'][0], strpos($_SERVER['argv'][0], ';') + 1) : '';。我已更新您的答案以包含此内容。
      【解决方案8】:

      REQUEST_URI 由 Apache 设置,因此您不会通过 IIS 获得它。尝试在 $_SERVER 上执行 var_dump 或 print_r,看看那里存在哪些可以使用的值。

      【讨论】:

        【解决方案9】:

        URL 的后标题部分位于您的index.php 文件之后,这是一种无需使用 mod_rewrite 即可提供友好 URL 的常用方法。因此,posttitle 实际上是查询字符串的一部分,因此您应该能够使用 $_SERVER['QUERY_STRING']

        获取它

        【讨论】:

          【解决方案10】:

          在您使用$_SERVER['REQUEST_URI'] 的PHP 页面顶部使用以下行。这将解决您的问题。

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

          【讨论】:

            【解决方案11】:

            哦,sn-p的乐趣!

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

            【讨论】:

              【解决方案12】:

              大家都忘了http_build_url

              http_build_url($_SERVER['REQUEST_URI']);
              

              当没有参数传递给http_build_url 时,它会自动假定当前的 URL。我希望 REQUEST_URI 也会被包含在内,尽管它似乎是包含 GET 参数所必需的。

              上面的例子将返回完整的 URL。

              【讨论】:

              • 这需要pecl_http。
              • @OmarAbid 我推荐它。 :-)
              • 我理解你的立场。但是,当构建将在您无法控制的不同平台上使用的脚本时,您需要选择一些非常标准的东西。
              • 如果您正在构建库,则由您来定义需求。最初的问题根本没有解决这种情况。因此,命名所有备选方案是有意义的。
              【解决方案13】:

              我使用了以下代码,并且得到了正确的结果...

              <?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 那么你想删除它的行。
              【解决方案14】:

              在我的 apache 服务器中,这会以您正在寻找的确切格式为我提供完整的 URL:

              $_SERVER["SCRIPT_URI"]
              

              【讨论】:

                【解决方案15】:

                反向代理支持!

                一些更强大的东西。 注意它仅适用于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'])), '/'));
                }
                

                【讨论】:

                  猜你喜欢
                  • 2014-01-20
                  • 2019-09-24
                  • 1970-01-01
                  • 2011-01-15
                  • 2014-10-14
                  • 1970-01-01
                  • 1970-01-01
                  • 2020-11-06
                  • 1970-01-01
                  相关资源
                  最近更新 更多