获取 PHP 项目的根目录路径


Get Root Directory Path of a PHP project

我的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));