【问题标题】:Problem Getting Root URL in PHP在 PHP 中获取根 URL 的问题
【发布时间】:2011-03-06 20:35:50
【问题描述】:

我在使用我编写的这个 PHP 函数 获取 根 URL 时遇到问题。我可以得到它,但是我必须为每个服务器设置例外情况,但我想要一个一致的函数来代替。你能告诉我如何解决它吗?

我将它放在给定网站的根文件夹中,在我的 Ubuntu 工作站上,它位于 /var/www/website 下,但在我的 CentOS 服务器上,它可能位于 /home/me/website 下。它可以在我的工作站上运行,但在服务器上由于某种原因我必须制作不同的版本。此外,我还必须为另一个似乎也不喜欢该功能的 CentOS 服务器制作另一个版本。在这个问题的结尾,我还列出了一些背景信息,说明我为什么要这样做。

工作站版本

public function getRootURL() {
  $sTemp = str_replace($_SERVER['DOCUMENT_ROOT'],'',__DIR__);
  $sTemp = str_replace($sTemp, '', $_SERVER['REQUEST_URI']);
  $sPageURL = (@$_SERVER['HTTPS'] == 'on') ? 'https://' . $_SERVER['SERVER_NAME'] : 'http://' . $_SERVER['SERVER_NAME'];
  $sPageURL .= ($_SERVER['SERVER_PORT'] != 80) ? ':' . $_SERVER['SERVER_PORT'] . $_SERVER['REQUEST_URI'] : $_SERVER['REQUEST_URI'];
  $sRootURL = str_replace($sTemp,'',$sPageURL);
  $sRootURL = rtrim($sRootURL, '/') . '/';
  $sRootURL = (strpos(' ' . $sRootURL, '://') === FALSE) ? $sPageURL : $sRootURL;
  return $sRootURL;
}

服务器版本

public function getRootURL() {
  $sTemp = str_replace($_SERVER['DOCUMENT_ROOT'],'',__DIR__);
  $sTemp = str_replace($sTemp, '', $_SERVER['REQUEST_URI']);
  $sPageURL = (@$_SERVER['HTTPS'] == 'on') ? 'https://' . $_SERVER['SERVER_NAME'] : 'http://' . $_SERVER['SERVER_NAME'];
  $sPageURL .= ($_SERVER['SERVER_PORT'] != 80) ? ':' . $_SERVER['SERVER_PORT'] . $_SERVER['REQUEST_URI'] : $_SERVER['REQUEST_URI'];
  $sRootURL = str_replace($sTemp,'',$sPageURL);
  $sRootURL = rtrim($sRootURL, '/') . '/';
  $sRootURL = (strpos(' ' . $sRootURL, '://') === FALSE) ? $sPageURL : $sRootURL;
  if (strpos(' ' . $sRootURL, 'mycentosserver.com')>0) {
    $sRootURL .= 'website/';
  }
  return $sRootURL;
}

在服务器版本上,请注意“mycentosserver.com” if/then 语句——这就是区别。

替代服务器版本

function getRootURL() {
  $sTemp = str_replace($_SERVER['DOCUMENT_ROOT'],'',__DIR__);
  $sTemp = str_replace($sTemp, '', $_SERVER['REQUEST_URI']);
  $sPageURL = (@$_SERVER['HTTPS'] == 'on') ? 'https://' . $_SERVER['SERVER_NAME'] : 'http://' . $_SERVER['SERVER_NAME'];
  $sPageURL .= ($_SERVER['SERVER_PORT'] != 80) ? ':' . $_SERVER['SERVER_PORT'] . $_SERVER['REQUEST_URI'] : $_SERVER['REQUEST_URI'];
  $sRootURL = str_replace($sTemp,'',$sPageURL);
  $sRootURL = rtrim($sRootURL, '/') . '/';
  $sRootURL = (strpos($sRootURL, '://') === FALSE) ? $sPageURL : $sRootURL;
  $sRootURL .= 'website2/'; // heck, I give up -- strange Apache problem on this server
  return $sRootURL;
}

背景

通常我会使用 MVC 框架,但我有一个客户想要在我离开时编辑内容,并且不喜欢 MVC 并且不理解它。他具有简单的 PHP 技能。所以,我使用一个看起来像这样的 .htaccess 来处理漂亮的 URL,以及在 URL 末尾可以出现斜杠的 URL,或者:

Options -Indexes +FollowSymlinks -MultiViews
RewriteEngine on

#No slash on the end of the url and not a real file/folder? then show x.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^[^/]*$ "$0.php" [nc]

#slashes on the end still and not a real file/folder, then remove them
RewriteCond %{REQUEST_URI} ^(.*)//(.*)$
RewriteRule . %1/%2 [R=301,L]

#if still here, and not a real file/folder, then show x.php in the alternative way
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)/$ "$1.php" [nc]

并且正在创建像 _css、_js、_classes 等子文件夹——试图让事情变得相当简单。每个页面在顶部都有 PHP,然后在 HTML 的底部有参数。这是为了尝试消除意大利面条式代码。客户端似乎喜欢这样,虽然我更喜欢 MVC,尤其是出于这个根 URL 的原因。

但请注意,使用 .htaccess 技术时,在某些情况下我的 HTML 可能没有正确的相对路径,例如有人在 URL 的末尾添加斜杠,因此我必须在 HTML 中使用标签来清除内容使用相对路径。这就是 getRootURL() 函数必须正常工作的原因。

【问题讨论】:

    标签: php .htaccess relative-path base-tag


    【解决方案1】:

    这个怎么样?

    function getRootURL() {
      $protocol   = empty($_SERVER['HTTPS'])? 'http' : 'https';
      $servername = $_SERVER['SERVER_NAME'];
      $serverport = $_SERVER['SERVER_PORT']=='80'? '' : ':' . $_SERVER['SERVER_PORT'];
      $path       = str_replace('\\', '/', substr(dirname(__FILE__), strlen($_SERVER['DOCUMENT_ROOT'])));
    
      return $protocol . '://' . $servername . $serverport . $path;
    }
    

    只要文件确实位于项目的根目录中,__FILE__ 就应该可以工作(否则再添加几个dirname()s。


    顺便说一句,如果您担心“有人在 URL 末尾添加斜杠”,为什么不直接将 /? 添加到您的 RewriteRule 中?

    【讨论】:

    • 如果用户请求的 PHP 文件放置在网站根目录下的目录中怎么办?假设像 /var/www 这样的文档根目录,而网站位于 /var/www/website/ 下,因此根 url 是 domain.com/website 并且 http 请求是针对 domain.com/website/a/b/c.php 您的功能无法得到 domain.com/website以上?因为它是关于特定应用程序 URL 而不是服务器 URL
    • @rahmanisback - Volomike 说他坚持 [根生成文件] 在给定网站的根文件夹中。所以dirname(__FILE__)会翻译成网站的根目录。这样,它就不是特定于应用程序的。因此,正如我在回答中提到的那样 - 只要具有函数定义的文件位于网站的根目录中,它就应该正确翻译。
    • @Czechnology:谢谢!我在 3 种情况下测试了您的代码——2 种完全 CentOS 配置,以及一种 Ubuntu 10.04 桌面配置(我的工作站)。 它在所有 3 种情况下都有效。 唯一的改进是我在末尾添加了一个 rtrim() 检查以删除任何结尾斜杠(如果可能存在的话),然后添加另一个以便我的 BASE 标签喜欢它。同样,我将它保存在 _classes 子文件夹中,然后将“/_classes”从路径中删除。
    • @Czechnology:如果您对 .htaccess 文件有一些具体的关于您可能会发现的任何优化的建议,我很想看到它。我不太明白你的/?完全的想法。
    • @Volomike,我没有任何优化,在这些情况下,我通常将我的漂亮网址直接添加到 .htaccess 文件中(我并不是说这是一种好的/正确的方法)。但我的意思是,如果您将/? 放在 RewriteRule 的条件部分的末尾,您不必担心 url 末尾的可选斜杠。跨度>
    【解决方案2】:

    如果我理解正确,您的 CentOS 安装不在虚拟主机文档根目录中,而是在您的 Ubuntu 工作站上。

    在这种情况下,有两个不同的函数实现对我来说似乎很自然。 只需在某个 ENV var 或 SERVER_NAME 上添加一个 IF 条件,然后使用一个或另一个。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-29
      • 2015-11-25
      相关资源
      最近更新 更多