PHP 是不是包含相对于文件或调用代码的路径?

Posted

技术标签:

【中文标题】PHP 是不是包含相对于文件或调用代码的路径?【英文标题】:Are PHP include paths relative to the file or the calling code?PHP 是否包含相对于文件或调用代码的路径? 【发布时间】:2011-11-14 18:45:59 【问题描述】:

我无法理解有关 php 相对包含路径的规则集。如果我运行文件 A.PHP- 并且文件 A.PHP 包含包含文件 C.PHP 的文件 B.PHP,那么 C.PHP 的相对路径应该与 B.PHP 的位置相关,还是与 A 的位置相关.PHP?也就是说,从哪个 file 调用包含是否重要,或者仅是当前工作目录是什么 - 以及决定当前工作目录的因素是什么?

【问题讨论】:

我认为比公认的答案更准确:***.com/a/23902890/1636522. 【参考方案1】:

它与主脚本相关,在本例中为 A.php。请记住,include() 只是将代码插入到当前运行的脚本中。

也就是说,从哪个文件调用包含是否重要

没有。

如果您想制作这很重要,并相对于 B.php 进行包含,请使用 __FILE__ 常量(或自 PHP 5.2 IIRC 起为 __DIR__),它将始终指向代码行所在的文字当前文件。

include(dirname(__FILE__)."/C.PHP");

【讨论】:

@Pekka- 真棒- 正是我想要的。欲了解更多信息,请参阅***.com/questions/2184810/… 您也可以使用__DIR__ 来达到这个目的。 这个答案有点矫枉过正:不需要include(dirname(__FILE__)."/C.PHP");,因为include("C.PHP");就足够了(是的!C.PHP可以和B.PHP在同一个目录中)只有当有两个时它可能会失败项目中的 C.PHP 文件。 为了更清楚:如果包含路径中没有“./”或“../”前缀,则它相对于 B.php 和 A.php。请参阅下面的答案。【参考方案2】:

@Pekka 把我带到了那里,但只是想分享我学到的东西:

getcwd() 返回您开始执行的文件所在的目录。

dirname(__FILE__)返回包含当前执行代码的文件目录。

使用这两个函数,您始终可以构建一个相对于您需要的包含路径。

例如,如果 b.php 和 c.php 共享一个目录,则 b.php 可以包含 c.php,如:

include(dirname(__FILE__).'/c.php');

无论从哪里调用 b.php。

事实上,这是建立相对路径的首选方式,因为额外的代码使 PHP 不必遍历 include_path 以尝试定位目标文件。

来源:

Difference Between getcwd() and dirname(__FILE__) ? Which should I use?

Why you should use dirname(__FILE__)

【讨论】:

我想添加一些东西,我有一个名为 csb.php 的文件,包含一个文件夹中的函数文件,函数文件包含一个与函数文件,当我尝试从 t.php 文件夹中包含一个名为 csb.php 的文件时,它开始包含调用函数文件的相同 csb.php,但是当我将第二个 csb.php 更改为 csbe.php 它开始马上工作。所以,看起来它优先考虑第一个文件夹,然后是第二个包含文件夹!【参考方案3】:

    如果包含路径不以./../ 开头,例如:

    include 'C.php'; // precedence: include_path (which include '.' at first),
                     // then path of current `.php` file (i.e. `B.php`), then `.`.
    

    如果包含路径以./../ 开头,例如:

    include './C.php';  // relative to '.'
    
    include '../C.php'; // also relative to '.'
    

上面的...是相对于getcwd()的,默认为.php文件入口的路径(即A.php)。

在 PHP 5.4.3 上测试(构建日期:2012 年 5 月 8 日 00:47:34)。

(还要注意chdir()可以改变getcwd()的输出。)

【讨论】:

综上所述,首先在A.php的路径中搜索C.php,然后如果include中没有前缀'./'或'../'则搜索B.php的路径。 (假设 PHP 的默认设置) 感谢您提示我使用chdir(__DIR__) 解决问题。 [...] getcwd(),默认为入口 .php 文件的路径 [...] - 不一定是真的。如果我在命令行上运行 PHP,那么 getcwd() 指的是 shell 的当前工作目录,无论我调用哪个 .php 文件。不过,我可以想象,如果 PHP 在 Web 服务器环境中运行,该环境会将当前工作目录初始化为条目 .php 文件。通过 Homebrew 安装 PHP 7.2.2 在 macOS 上测试。【参考方案4】:

Pekka 接受的答案是不完整的,并且在一般情况下具有误导性。如果文件作为相对路径提供,则被调用的语言构造include 将按以下方式搜索它。

首先会经过环境变量include_path的路径,可以用ini_set设置。如果失败,它将在调用脚本自己的目录中搜索dirname(__FILE__)__DIR__ with php >= 5.3。)如果这也失败,那么它只会在工作目录中搜索!事实证明,默认情况下,环境变量include_path. 开头,即当前工作目录。这是它首先在当前工作目录中搜索的唯一原因。见http://php.net/manual/en/function.include.php。

根据给定的文件路径包含文件,如果没有给出,则 指定的 include_path。如果文件在 include_path, include 最终会检入调用脚本自己的 失败前的目录和当前工作目录。

因此,问题第一部分的正确答案是,包含的调用脚本的位置确实很重要。问题最后一部分的答案是,在 Web 服务器上下文中,initial 工作目录是被调用脚本的目录,该脚本包含所有其他脚本,同时由 PHP 处理。在命令行上下文中,初始工作目录是在提示符处调用 php 时的任何目录,不一定是被调用脚本所在的目录。但是,当前 工作目录可以在运行时使用 PHP 函数 chdir 进行更改。见http://php.net/manual/en/function.chdir.php。

添加此段落是为了评论其他答案。有人提到依赖include_path 的健壮性较差,因此最好使用完整路径,例如./path__DIR__ . /path。有人甚至说依赖工作目录. 本身并不安全,因为它可以更改。但是,有时,您需要依赖环境值。例如,您可能希望将include_path 设置为空,以便调用脚本的目录是它将首先搜索的位置,甚至在当前工作目录之前。代码可能已经从外部来源定期编写和更新,并且您不想在每次更新代码时重新插入前缀 __DIR__

【讨论】:

"如果失败,它将在调用脚本自己的目录中搜索dirname(__FILE__) (__DIR__) php >= 5.3.)" 你确定吗?它记录在哪里?我希望你是错的,PHP 确实 not__FILE____DIR__ 用于 this 目的,因为这会立即破坏包括来自 的“兄弟”脚本符号链接的! :-o (幸运的是,在我的 7.1 设置中,这似乎在这里工作正常。)【参考方案5】:

简短回答:它与包含脚本有关。

TFM 解释正确:

如果在 include_path 中找不到该文件,则 include 将检查调用脚本的目录和当前工作目录

所以,如果 /app/main.phpinclude("./inc.php") 会找到 /app/inc.php

./ 不是绝对必要的,但会删除对 include_path 的任何依赖。

我不会依赖在当前工作目录中查找包含文件,以防有人用chdir() 更改它。

【讨论】:

那么如果以./开头的字符串,是先检查调用脚本的目录还是先检查当前工作目录? @Denis Howe 不,如果您的包含路径以./ 开头,则您已经依赖于当前工作目录。即 chdir("/app/other") 将使 include("./inc.php") 失败。因此,在这种情况下使用include("inc.php") 是安全的。 @Pacerier 如果字符串以 ./ 或 ../ 开头,它只检查当前工作目录。 (调用脚本(B.php)的include_path和目录都被忽略了)。请参阅我的答案以了解更多详细信息。【参考方案6】:
dir
-> a.php
-> c.php

- dir2 
-> b.php

要将a 包含在b 中,您需要include("../a.php");

要将b 包含在c 中,您需要include("dir2/b.php");

【讨论】:

@Olli-你错过了问题的重点-我问的是当包含链接时如何确定相对路径。

以上是关于PHP 是不是包含相对于文件或调用代码的路径?的主要内容,如果未能解决你的问题,请参考以下文章

file_exists 和包含相对路径的路径(“/../”)

require或include相对路径多层嵌套引发的问题

在带有符号链接的可执行文件中使用相对路径

从相对路径和/或文件名解析绝对路径

php获取上级文件绝对路径

java中如何判断web工程中图片的绝对路径是不是存在