<?php
$script_name = $_SERVER['SCRIPT_NAME']; // to get www.myurl.com
// create a constant out of the server_name
define('HTTP_HOST', $_SERVER['HTTP_HOST'].'/');
$path_parts = pathinfo($script_name); // returns an array with path names
// get the filename with the extension
$file_name = $path_parts['filename'] . '.' . $path_parts['extension'];
// get the directory which the script lives in
$dir = rtrim($script_name, $file_name);
// trim of the left slash since it was added on the end of the HTTP_HOST constant
$dir = ltrim($dir, '/');
// store the server name and directory paths in a variable
$dir = HTTP_HOST.$dir;
echo $dir; // will return f.ex. "www.myurl.com/dir1/dir2/dir3/"
假设我有一个名为“testfile.php”的文件,它位于“www.myurl.com/dir1/dir2/dir3
”目录“dir3”下,因此完整的网址将为“www.myurl.com/dir1/dir2/dir3/testfile.php
”。
如果我在路径文件中声明URL加上完整目录路径的常量,或者我在f.ex我的索引文件中包含的一些配置文件,并在testfile.php中调用该常量,则回显它。它将回显“www.myurl.com/dir1/dir2/dir3/
”。
谢谢。
答案 0 :(得分:2)
众所周知,完美主义很难实现。这意味着通常有更好的方法来实现目标。
查看问题中的代码,我很确定,有更好的方法可以实现您的目标。回到你的问题:
我的问题是,这种方法是否可以接受,或者是否有更好的方法来实现具有指定文件的目录路径的URL?
答案是肯定的。例如,更好的方法是将实现封装到它自己的对象中,例如,文件映射器。这将使您始终能够使用可随时间变化的最佳方式。
您应该至少使用一个封装逻辑的函数来将文件名映射到web目录。还可以使用所谓的输入,并在代码的顶部处理它们:
function get_webdirectory_of_file($file)
{
# input (and validation)
$host = $_SERVER['HTTP_HOST'];
$docroot = $_SERVER['DOCUMENT_ROOT'];
if (!is_file($file) {
throw new Exception('Not a file');
}
if (!$host) {
throw new Exception('No HTTP_HOST found.');
}
if (!$docroot ) {
throw new Exception('No DOCUMENT_ROOT found.');
}
$len = strlen($docroot);
if (substr($file, 0, $len) !== $docroot) {
throw new Exception('Unable to map file out of document root to document root');
}
# processing
$dir = substr(dirname($file), $len);
# output
return $host . $dir;
}
由于代码位于自己的函数内部,因此您可以随着时间的推移对其进行改进,而无需更改(大部分)应用程序的其余部分。使用对象更好,因为你可以更容易地替换它使整体更灵活,但从函数开始也是一个好主意。用法示例:
echo get_webdirectory_of_file(__FILE__);
查看您的代码:
<?php
$script_name = $_SERVER['SCRIPT_NAME']; // to get www.myurl.com
请查看PHP手册,了解使用$_SERVER
变量的问题。
// create a constant out of the server_name
define('HTTP_HOST', $_SERVER['HTTP_HOST'].'/');
由于$_SERVER['HTTP_HOST']
已经存在,因此无需创建常量。这只会隐藏稍后使用该常量相关的问题。我建议你从你的代码中删除那个常量。
$path_parts = pathinfo($script_name); // returns an array with path names
// get the filename with the extension
$file_name = $path_parts['filename'] . '.' . $path_parts['extension'];
实际上,你在这里寻找的是basename
,就是这样:
$file_name = basename($_SERVER['SCRIPT_NAME']);
现在开始使用您的代码:
// get the directory which the script lives in
$dir = rtrim($script_name, $file_name);
这有点疼。请重新阅读rtrim
函数的功能。你不想在这里使用它。
// trim of the left slash since it was added on the end of the HTTP_HOST constant
$dir = ltrim($dir, '/');
在这种情况下使用ltrim
可能看起来很聪明,但通常这是一种气味,你不明白你实际做了什么以及你使用哪些输入值。与使用常量相比:
// store the server name and directory paths in a variable
$dir = HTTP_HOST.$dir;
您可以在此处重复使用变量名称($dir
)。这通常没有用。另外,如果您首先添加/
仅删除/
上面一行,这没有任何意义。你可以放过两个。
echo $dir; // will return f.ex. "www.myurl.com/dir1/dir2/dir3/"
当然,问题在于您需要什么以及它的稳定性。如上所述,我完全相信,有更好的方法可以做到这一点,是的。
答案 1 :(得分:0)
这应该有效:
$dir = $_SERVER['HTTP_HOST'] . substr(dirname(__FILE__), strlen($_SERVER['DOCUMENT_ROOT']));
答案 2 :(得分:0)
看看是否有效:
function getCurrentPageURL() {
$protocol = "http";
if ($_SERVER["HTTPS"] == "on") {$protocol .= "s";}
$protocol .= "://";
$server = $_SERVER["SERVER_NAME"];
if ($_SERVER["SERVER_PORT"] != "80") {
$page = $server . ":" . $_SERVER["SERVER_PORT"].$_SERVER["REQUEST_URI"];
} else {
$page = $server . $_SERVER["REQUEST_URI"];
}
return $protocol . $pageURL;
}
此解决方案考虑了不同的端口和HTTPS协议。