PHP:查找项目根的绝对URL
我有一个PHP项目,应该安装在不同的服务器上。 它在项目根目录中有一个名为PHP:查找项目根的绝对URL,php,apache,Php,Apache,我有一个PHP项目,应该安装在不同的服务器上。 它在项目根目录中有一个名为includes.php的包含文件,可以从整个项目的多个位置调用该文件,比如从文件file1.php(与includes.php位于同一位置)、subdir/file2.php和subdir2/file3.php。includes文件包含一个函数,该函数应该返回我整个项目的绝对URL,例如http://www.myserver.com/myproject/,无论从哪个文件调用函数 我不能使用$\u SERVER[“REQ
includes.php
的包含文件,可以从整个项目的多个位置调用该文件,比如从文件file1.php
(与includes.php
位于同一位置)、subdir/file2.php
和subdir2/file3.php
。includes文件包含一个函数,该函数应该返回我整个项目的绝对URL,例如http://www.myserver.com/myproject/
,无论从哪个文件调用函数
- 我不能使用
,因为这会返回调用函数的文件的URL(这会有所不同)。我不想传递一个表示“上两个目录”之类的参数,因为有很多地方可以调用这个URL函数$\u SERVER[“REQUEST\u URI”]
- 我不能使用
和\\\\\\\
$\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\/code>服务器['DOCUMENT\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\/code>的子目录中。(我正在为我的学校写这个项目,但应该分发给其他学校。)
$\u服务器[“REQUEST\u URI”]
,删除文件部分,并使用get\u headers()
检查是否可以在此目录中找到已知文件(dummy.php
)。如果没有,我检查父目录等等。不幸的是,get_headers()
在我们的学校服务器中没有返回任何内容(不过它在我家的考试系统上工作)
一个有效的解决方案(但我并不喜欢)是将项目根URL放在配置文件中
有人对此有其他想法吗?提前谢谢
编辑:
好的,我自己找到了一个适合我的解决方案。我仍然对如何做得更好持开放态度,也许不需要使用debug\u 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;
}
函数urlPath()
{
$trace=debug_backtrace();
$first_frame=$trace[count($trace)-1];
//最低的一帧给出了第一次调用的文件名
$callerdir=dirname($first_frame['file']);
$includedir=dirname(文件名);
$rootLength=strlen($includedir);
$subDir=substr($callerdir,$rootLength);
$subdirDepth=子目录计数($subDir,目录分隔符);
//我使用的事实是,include文件位于项目根文件夹中,因此
//文件夹路径必须是任何其他文件的文件夹路径的前缀。我将删除此选项
//为路径分隔符添加前缀并计数,以获得“相对深度”。
$pageURL='http';
如果(isset($\u服务器[“HTTPS”])&&&$\u服务器[“HTTPS”]=“打开”)
{
$pageURL.=“s”;
}
$pageURL.=“:/”$\u服务器[“服务器名称”];
如果(isset($\u服务器[“服务器\u端口”])和&$\u服务器[“服务器\u端口”]!=“80”)
{
$pageURL.=“:”$\u服务器[“服务器\u端口”];
}
$pageURL.=$\u服务器[“请求URI”];
//我得到了呼叫页面的绝对URL
对于($i=0;$i我想要类似的东西。但是想要省略文件名
我希望这对你有帮助,伙计!
原始方法:
这花了我一段时间来完善,我把它作为不需要变量的人或项目的一个例子。对于你的情况,你可以做出一个全局的选择
$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__));
或者更简单的方法:)
示例输出:(https、http、端口等)
这个“返回项目根url”函数所在的文件是否与项目根有已知的关系?或者您是否有前端控制器(每个请求都在其中发送的文件)?是的,includes.php位于项目根目录中。否,我没有前端控制器。
$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://example.xyz/base/path/without/file/
http://another.example.com/uploads/test/
http://www.return.url:81/blah/blahblah/example/