我的PHP项目中有这个文件夹结构。(如日食所示(
-MySystem
+Code
+Data_Access
-Public_HTML
+css
+js
+Templates
-resources
当我尝试此代码时
echo $_SERVER['DOCUMENT_ROOT']
输出为
D:/工作区
如何在不对文件夹名称进行硬编码的情况下获取系统根目录(MySystem
(的路径?
对于 PHP>= 5.3.0 尝试
PHP 魔术常量。
__DIR__
并让你的道路相对。
对于 PHP <5.3.0 尝试
dirname(__FILE__)
当你这么说时
$_SERVER['DOCUMENT_ROOT']
包含以下路径:
D:/workspace
那么D:
这就是你要找的,不是吗?在这种情况下,您可以通过斜杠分解字符串并返回第一个:
$pathInPieces = explode('/', $_SERVER['DOCUMENT_ROOT']);
echo $pathInPieces[0];
这将输出服务器的根目录。
更新:当您使用常量DIRECTORY_SEPARATOR
而不是硬编码斜杠 ( '/'
( 时,此代码也可以在 Windows 下工作。
更新 2:$_SERVER
全局变量并不总是可用。例如,在命令行 (cli( 上。所以你应该使用 __DIR__
而不是 $_SERVER['DOCUMENT_ROOT']
. __DIR__
返回 php 文件本身的路径。
使用 PHP 函数:
getcwd()
获取当前工作目录。
指出Wordpress处理这个问题的方式:
define( 'ABSPATH', dirname( __FILE__ ) . '/' );
由于Wordpress在整个网络上的使用量非常大,并且在本地也能正常工作,因此我对这种方法非常信任。你可以在wordpress的底部找到这个定义wp-config.php
file
目前,PHP 本身并没有提供一种确定获取项目根目录的方法。
但是你可以自己实现一个非常简单的方法,它完全可以完成你正在寻找的东西。
溶液
在你的项目中创建一个新文件,比如说D:/workspace/MySystem/Code/FilesManager.php
(使用最适合你的名称和路径(。然后,使用以下代码:
<?php
class FilesManager
{
public static function rootDirectory()
{
// Change the second parameter to suit your needs
return dirname(__FILE__, 2);
}
}
现在你可以这样做,假设D:/workspace/MySystem/Code/a/b/c/Feature.php
:
echo FilesManager::rootDirectory();
预期结果应该是:
"D:/workspace/MySystem"
无论您的"功能"文件位于项目中的哪个位置,输出都将是相同的。
解释
dirname 用于返回第一个参数的父目录。我们使用魔术常数__FILE__
给它FilesManager.php
路径。第二个参数指示在层次结构中向上上升多少次。在这种情况下,我们需要执行两次,但这实际上取决于您将文件放在层次结构中的位置。如果您只需要起床一次,则可以省略第二个参数,这意味着文件位于根目录中。但是,您可以直接返回__DIR__
。
无论根位于服务器上的哪个位置,此解决方案都可以保证工作。除非您最终将实用程序类移动到层次结构中的其他位置。
附加说明
出于以下原因,我会避免使用DOCUMENT_ROOT(根据这个答案(:
- 它使您的应用程序依赖于服务器。
- Apache 安装程序可能会提供不正确的根目录路径。
dirname(__FILE__)
很有用,但会获取相对于当前文件 URL 的当前路径,以防您在远离根目录的其他目录中,例如包含,并且您需要从根目录获取文件夹,您可以使用整数参数 2 将向上 1 级,依此类推
echo dirname(__FILE__, 2);
以前
C:''laragon''www''x''include''reports''charts
后
C:''laragon''www''x''reports''charts
报告是根目录 x 内的文件夹
你可以试试: $_SERVER['PATH_TRANSLATED']
报价:
在服务器完成任何虚拟到真实映射之后,当前脚本的基于文件系统(不是文档根目录(的路径。注意:从 PHP 4.3.2 开始,
PATH_TRANSLATED
不再隐式设置在 Apache 2 SAPI 下,这与 Apache 1 中的情况相反,当 Apache 1 未填充时,它被设置为与SCRIPT_FILENAME
服务器变量相同的值。
进行此更改是为了符合 CGI 规范,即只有在定义了PATH_INFO
的情况下,PATH_TRANSLATED才应存在。Apache 2 用户可以在httpd.conf
中使用AcceptPathInfo = On
来定义PATH_INFO
源:php.net/manual
你也可以使用realpath。
realpath(".")
返回文档根目录。
您可以使用您的特定路径调用 realpath。请注意,如果目标文件夹或文件不存在,它将不起作用。在这种情况下,它将返回 false,这对于测试文件是否存在可能很有用。
就我而言,我需要为要写入磁盘的新文件指定路径,解决方案是附加相对于文档根目录的路径:
$filepath = realpath(".") . "/path/to/newfile.txt";
希望这对任何人都有帮助。
echo $pathInPieces = explode(DIRECTORY_SEPARATOR , __FILE__);
echo $pathInPieces[0].DIRECTORY_SEPARATOR;
总结
此示例假设您始终知道 apache 根文件夹的位置是 '/var/www/',并且您正在尝试查找下一个文件夹路径(例如 '/var/www/my_website_folder'(。这也适用于脚本或 Web 浏览器,这就是有附加代码的原因。
代码 PHP7
function getHtmlRootFolder(string $root = '/var/www/') {
// -- try to use DOCUMENT_ROOT first --
$ret = str_replace(' ', '', $_SERVER['DOCUMENT_ROOT']);
$ret = rtrim($ret, '/') . '/';
// -- if doesn't contain root path, find using this file's loc. path --
if (!preg_match("#".$root."#", $ret)) {
$root = rtrim($root, '/') . '/';
$root_arr = explode("/", $root);
$pwd_arr = explode("/", getcwd());
$ret = $root . $pwd_arr[count($root_arr) - 1];
}
return (preg_match("#".$root."#", $ret)) ? rtrim($ret, '/') . '/' : null;
}
例
echo getHtmlRootFolder();
输出:
/var/www/somedir/
详:
基本上首先尝试获取DOCUMENT_ROOT如果它包含 '/var/www/' 然后使用它,否则获取当前目录(项目中存在很多(,并根据$root路径的计数获取下一个路径值。注意:添加了 rtrim 语句,以确保路径在所有情况下都返回以"/"结尾的路径。它不检查它是否需要大于/var/www/,它也可以返回/var/www/作为可能的响应。
我有用,
realpath("../")
您可以使用此../
参数来指向。它将指向 1 步回到您的实际工作文件
我在这里找到了答案:https://stackoverflow.com/a/24338828/7478226
<base href="http://localhost/abc/" />
我使用此代码。它允许用户定义的文件夹在第一行声明为$root。然后,它使用 __FILE__ 获取实际根。这是使用 DIRECTORY_SEPARATOR 分解的(以便它适用于任何系统(。循环在找到$root之前创建一个仅包含部分的新数组。然后将$root推送到阵列。新阵列再次使用DIRECTORY_SEPARATOR作为胶水内爆。结果存储在名为 REAL_ROOT 的新全局中。
让我知道它是否有任何帮助或任何好处!
$root = 'folder_you_want_as_root';
$currentDirectory = __FILE__;
$parts = explode(DIRECTORY_SEPARATOR,__FILE__);
$newParts = [];
foreach($parts as $part){
if($part==$root){
break;
}
$newParts[] = $part;
}
$newParts[] = $root;
define('REAL_ROOT',implode(DIRECTORY_SEPARATOR,$newParts));