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.php 说 include("./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 是不是包含相对于文件或调用代码的路径?的主要内容,如果未能解决你的问题,请参考以下文章