【问题标题】:Get Root Directory Path of a PHP project获取 PHP 项目的根目录路径
【发布时间】:2011-12-29 14:00:25
【问题描述】:

我的 PHP 项目中有这个文件夹结构。 (这个在eclips中显示)

-MySystem
    +Code
    +Data_Access
    -Public_HTML
        +css
        +js
        +Templates
    -resources

当我尝试这段代码时

echo $_SERVER['DOCUMENT_ROOT']

输出是

D:/工作区

如何在不硬编码文件夹名称的情况下获取系统根目录 (MySystem) 的路径?

【问题讨论】:

    标签: php


    【解决方案1】:

    对于 PHP >= 5.3.0 试试

    PHP magic constants.

    __DIR__
    

    并使您的路径相对。

    对于 PHP 试试

    dirname(__FILE__)
    

    【讨论】:

    • 这太棒了,我试过 $_SERVER['DOCUMENT_ROOT']、dirname()、$_SERVER['SCRIPT_NAME'] 等,但效果很好!
    • 这取决于你在哪里使用 __DIR__ 。它是相对于文件本身的,所以如果在包含的子目录中,它不会只返回你的根目录。
    • 不会给出根目录
    • 对于偶然发现此答案以寻找所提问题答案的任何人的快速说明,DIR 获取当前文件的目录而不是项目根目录,除非您调用它项目根目录中的文件,但由于 php 没有项目的概念,所有路径都必须是绝对或相对于当前位置
    • 请不要仅仅因为它对您有所帮助而对未正确解决问题的答案进行投票。
    【解决方案2】:

    当你这么说时

    $_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文件本身的路径。

    【讨论】:

    • 你可以用__DIR__代替$_SERVER['DOCUMENT_ROOT']。
    • 对不起,如果我没有正确解释我的问题,我真正需要的是 'D:/workspace/MySystem'
    • 如果你的根目录路径是 /var/public/www" 那么使用这个方法数组中的第一个字符串将为空 (0)/(1)/(2)/ (3). 根将是第二个字符串 $pathInPieces[1]
    【解决方案3】:

    使用PHP函数:

    getcwd()

    获取当前工作目录。

    【讨论】:

    • 返回当前执行文件路径。不是根路径
    【解决方案4】:

    我想指出 Wordpress 处理这个问题的方式:

    define( 'ABSPATH', dirname( __FILE__ ) . '/' );
    

    由于 Wordpress 在整个网络上的使用量很大,并且在本地也能正常工作,我非常信任这种方法。你可以在你的 wordpress wp-config.php 文件底部找到这个定义

    【讨论】:

    • 我猜这只有在你有两级目录时才有效。对?我的意思是,当从 base_project_directory/folder1/folder2/folder3/file.php 调用它时,它不会返回 base_project_directory。
    • “由于 Wordpress 在整个网络上的使用量很大,而且在本地也能正常工作,我非常信任这种方法。”鉴于 WP 代码质量和安全记录,我认为这不是一个特别好的论据。
    • @AlexBarker 我会反驳你暗示 WP 的安全记录不佳的事实。它实际上非常安全,并且拥有一支专注于安全性的响应式团队 - 近年来,核心几乎没有被利用的安全问题(包括早在您发表评论时)。
    • 实际上这行不通。没有调查太多,但看起来双 dirname 实际上剥离了一个目录(可能不是来这个线程的人想要的 -> 即我)
    • @43matthew 你是对的。过去它以这种方式工作,但显然不再如此。由于 WP 也更改了定义,因此我相应地更新了我的答案。感谢您指出这一点。
    【解决方案5】:

    目前,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用于返回第一个参数的父目录。我们使用magic constant __FILE__ 给它FilesManager.php 的路径。第二个参数告诉在层次结构中上升多少次。在这种情况下,我们需要执行两次,但这实际上取决于您将文件放在层次结构中的哪个位置。如果只需要启动一次,则可以省略第二个参数,即文件位于根目录下。但是,您可以直接返回__DIR__。

    无论根目录位于您的服务器上的哪个位置,都可以保证此解决方案有效。除非您最终将实用程序类移到层次结构中的其他位置。

    补充说明

    出于以下原因(根据answer),我会避免使用 DOCUMENT_ROOT:

    • 它使您的应用程序依赖于服务器。
    • Apache 安装程序可能会给出不正确的根目录路径。

    【讨论】:

    • dirname 的第二个参数很有帮助
    • 我尝试了您的解决方案,它在 localhost 上运行,但是当我在主机上使用它时,url 中添加了额外的 /\,
    【解决方案6】:

    你可以试试: $_SERVER['PATH_TRANSLATED']

    引用:

    在服务器完成任何虚拟到真实的映射之后,当前脚本的基于文​​件系统(不是文档根目录)的路径。注意:从 PHP 4.3.2 开始,PATH_TRANSLATED 不再在 Apache 2 SAPI 下隐式设置,这与 Apache 1 中的情况相反,在 Apache 1 中,当它未被填充时,它被设置为与 SCRIPT_FILENAME 服务器变量相同的值阿帕奇。
    进行此更改是为了符合 CGI 规范,即 PATH_TRANSLATED 仅在定义 PATH_INFO 时才应存在。 Apache 2 用户可以在httpd.conf 中使用AcceptPathInfo = On 来定义PATH_INFO

    来源: php.net/manual

    【讨论】:

      【解决方案7】:
      echo $pathInPieces = explode(DIRECTORY_SEPARATOR , __FILE__);
      echo $pathInPieces[0].DIRECTORY_SEPARATOR;
      

      【讨论】:

        【解决方案8】:

        您也可以使用realpath。

        realpath(".") 返回您的文档根目录。

        您可以使用您的特定路径调用 realpath。请注意,如果目标文件夹或文件不存在,它将不工作。在这种情况下,它将返回 false,这对于测试文件是否存在很有用。

        在我的情况下,我需要为要写入磁盘的新文件指定路径,解决方案是附加相对于文档根目录的路径:

        $filepath = realpath(".") . "/path/to/newfile.txt";

        希望这对任何人都有帮助。

        【讨论】:

        • 它有效,我认为这是最好的解决方案。通过阅读文档,我无法理解它为什么以及如何工作。 realpath() [...] resolves references to /./, /../ [...] and returns the canonicalized absolute pathname. 很好,但是. 表示当前目录,所以如果你将它作为参数传递,它是如何解析到root'当前目录的?我错过了什么?
        【解决方案9】:

        总结

        此示例假定您始终知道 apache 根文件夹的位置是“/var/www/”,并且您正在尝试查找下一个文件夹路径(例如“/var/www/my_website_folder”)。这也适用于脚本或网络浏览器,这就是为什么有额外的代码。

        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/ 作为可能的响应。

        【讨论】:

          【解决方案10】:
          dirname(__FILE__)
          

          很有用,但会获取相对于当前文件 URL 的当前路径,以防万一您位于远离根目录的其他目录中,例如包含,并且您需要从根目录获取文件夹,您可以使用整数参数 2 将升级 1 级并且以此类推

          echo dirname(__FILE__, 2);
          

          之前

          C:\laragon\www\x\includes\reports\charts

          之后

          C:\laragon\www\x\reports\charts

          reports 是根目录 x 内的文件夹

          【讨论】:

            【解决方案11】:

            这对我有用,

            realpath("../")
            

            您可以使用这个../ 参数来指向。它将指向您实际工作文件的 1 步

            【讨论】:

            • 这将返回路径,从 当前 文件向上一级
            猜你喜欢
            • 2023-02-07
            • 1970-01-01
            • 2023-03-02
            • 1970-01-01
            • 2012-07-21
            • 2014-10-12
            • 2017-01-29
            • 1970-01-01
            • 2012-11-25
            相关资源
            最近更新 更多