我有一个 PHP 项目,应该安装在不同的服务器上。
它在项目根目录中有一个名为 includes.php
的包含文件,可以从整个项目的多个位置调用该文件,比方说从文件 file1.php
(在同一个文件中)位置为 includes.php
)、subdir/file2.php
和 subdir2/file3.php
。 include 文件包含一个函数,该函数应该返回整个项目的绝对 URL,例如 http://www.myserver.com/myproject/
,无论该函数是从哪个文件调用的.
- 我无法使用
$_SERVER["REQUEST_URI"]
因为它返回调用该函数的文件的 URL(各不相同)。我不想传递一个表示“向上两个目录”或类似内容的参数,因为可以从很多地方调用此 URL 函数。 - 我不能使用
__FILE__
和$_SERVER['DOCUMENT_ROOT']
(这是一些人推荐的),因为我们的服务器有一些奇怪的配置,例如__FILE__
不在$_SERVER['DOCUMENT_ROOT']
的子目录中。 (我正在为我的学校编写该项目,但它应该分发给其他学校。)
我的最后一个解决方案是采用 $_SERVER["REQUEST_URI"]
,删除文件部分并使用 get_headers()
来检查是否存在已知文件(dummy.php
) 可以在此目录中找到。如果没有,我检查父目录等等。不幸的是,get_headers()
不会在我们的学校服务器中返回任何内容(不过它可以在我家里的测试系统上运行)。
一个可行的解决方案(但我不太喜欢)是将项目根 URL 放在配置文件中。
有人对此有其他想法吗?提前致谢!
编辑: 好的,我自己找到了一个适合我的解决方案。我仍然愿意接受评论,如何做得更好,也许不使用 debug_backtrace() ?有什么理由不使用这个功能吗?
function urlPath()
{
$trace = debug_backtrace();
$first_frame = $trace[count($trace)-1];
// the lowest frame gives us the filename from which the first call was made
$callerdir = dirname($first_frame['file']);
$includedir = dirname(__FILE__);
$rootLength = strlen($includedir);
$subDir = substr($callerdir, $rootLength);
$subdirDepth = substr_count($subDir,DIRECTORY_SEPARATOR);
// I use the fact that the include file is in the project root folder, so its
// folder path must be a prefix of any other file's folder path. I remove this
// prefix and count the number of path separators to get the "relative depth".
$pageURL = 'http';
if (isset($_SERVER["HTTPS"]) && $_SERVER["HTTPS"] == "on")
{
$pageURL .= "s";
}
$pageURL .= "://" . $_SERVER["SERVER_NAME"];
if (isset($_SERVER["SERVER_PORT"]) && $_SERVER["SERVER_PORT"] != "80")
{
$pageURL .= ":".$_SERVER["SERVER_PORT"];
}
$pageURL .= $_SERVER["REQUEST_URI"];
// I get the absolute URL of the calling page
for ($i = 0; $i <= $subdirDepth; $i++)
{
$idx = strrpos($pageURL,'/');
$pageURL = substr($pageURL, 0, $idx);
}
// I remove the required number of subdirectories plus one for the filename
return $pageURL;
}
最佳答案
我想要类似的东西。但希望省略文件名。
希望这对伙伴有帮助!
原始方法:
这花了我一段时间来完善,并且我保留了作为不需要变量的人员或项目的示例。根据您的情况,您可以创建一个全局的。
$current_url = (empty($_SERVER['HTTPS']) ? "http://" : "https://") . ($_SERVER['SERVER_NAME']) . (((empty($_SERVER['HTTPS']) ? 'http' : 'https') == "http" && $_SERVER['SERVER_PORT'] == 80 || (empty($_SERVER['HTTPS']) ? 'http' : 'https') == "https" && $_SERVER['SERVER_PORT'] == 443) ? "" : ":" . $_SERVER['SERVER_PORT']) . (preg_replace("!^". preg_replace("!". $_SERVER['SCRIPT_NAME'] ."$!", "", $_SERVER['SCRIPT_FILENAME']) ."!", "", __DIR__));
或者,更简单的方法:)
$protocol = ((!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off') || $_SERVER['SERVER_PORT'] == 443) ? "https://" : "http://";
$path = substr( dirname(__FILE__), strlen($_SERVER['DOCUMENT_ROOT']));
$current_url = $protocol . $_SERVER['HTTP_HOST'] . $path;
示例输出:(https、http、端口等)
https://example.xyz/base/path/without/file/
http://another.example.com/uploads/test/
http://www.return.url:81/blah/blahblah/example/
关于PHP:查找项目根目录的绝对URL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17510441/