我在理解PHP相对包含路径规则集方面遇到了麻烦。如果我运行文件A.PHP,并且文件A.PHP包含文件B.PHP,而文件B.PHP又包含文件C.PHP,那么C.PHP的相对路径是基于B.PHP的位置还是基于A.PHP的位置?也就是说,包含调用的文件是否重要,或者只有当前工作目录重要,而是什么决定了当前工作目录?
我在理解PHP相对包含路径规则集方面遇到了麻烦。如果我运行文件A.PHP,并且文件A.PHP包含文件B.PHP,而文件B.PHP又包含文件C.PHP,那么C.PHP的相对路径是基于B.PHP的位置还是基于A.PHP的位置?也就是说,包含调用的文件是否重要,或者只有当前工作目录重要,而是什么决定了当前工作目录?
这取决于主脚本,即此处的 A.php。请记住,include()
仅将代码插入当前运行的脚本中。
也就是说,调用 include 的文件是否有关系?
没有。
如果你想要让它有关系并且相对于 B.php 进行包含,请使用 __FILE__
常量(自 PHP 5.2 以来还可以使用 __DIR__
),它将始终指向包含该行代码的字面上的当前文件。
include(dirname(__FILE__)."/C.PHP");
__DIR__
来实现完全相同的目的。 - Nick Bedfordinclude(dirname(__FILE__)."/C.PHP");
,因为 include("C.PHP");
就足够了(是的!C.PHP可以和B.PHP在同一个目录下)。只有当项目中有两个C.PHP文件时才可能失败。 - Johnny Wong。
未出现在其中,PHP的include_path可能会配置错误,因此它不会查找当前工作目录。此外,工作目录可以通过入口点或使用chdir更改(如您的帖子所示)而更改。在通过相对包含项时,它需要浏览完整的include_paths列表,并且根据配置可能会找到“错误”的文件。使用绝对路径(例如__DIR__
,dirname(__FILE__)
等)要少出错得多。但是,如果您知道风险,请随意使用相对路径。 - Kevin Ydirname
函数有一个可选的第二个参数(整数类型),它使您能够相对于当前脚本遍历“n”个父目录。您可以在此处找到更多详细信息:https://www.php.net/manual/en/function.dirname.php - G M.
,.
也会被搜索到。在 PHP 文档中有这样的说明:“如果在 include_path 中找不到文件,include 最终会在调用脚本的目录和当前工作目录中进行搜索,直到失败为止。” - undefined@Pekka 指出了我的问题,但是我想分享一下我学到的内容:
getcwd()
返回执行脚本所在的目录。
dirname(__FILE__)
返回包含当前正在执行代码的文件的目录。
使用这两个函数,您可以始终构建与您需要的路径相关的包含路径。
例如,如果 b.php 和 c.php 共享一个目录,b.php 可以像下面这样包含 c.php:
include(dirname(__FILE__).'/c.php');
无论b.php从哪里调用,都可以使用这种方式。实际上,这是建立相对路径的首选方式,因为额外的代码使PHP无需尝试遍历include_path以定位目标文件。
来源:
./
或../
开头,例如:
include 'C.php'; // 优先级:include_path(首先包含'.'),
// 然后是当前`.php`文件的路径(即`B.php`),然后是`.`。
./
或../
开头,例如:
include './C.php'; // 相对于'.'
include '../C.php'; // 也相对于'.'
.
或 ..
是相对于 getcwd()
的,它默认为入口 .php
文件的路径(即 A.php
)对于某些Web服务器,如Apache。
在PHP 5.4.3上进行了测试(构建日期:2012年5月8日00:47:34)。
(还要注意 chdir()
可以更改 getcwd()
的输出。)
chdir(__DIR__)
来解决问题。 - HartleySangetcwd()
,默认为入口.php
文件的路径 [...] - 不一定是真的。如果我在命令行上运行PHP,则getcwd()
指的是shell的当前工作目录,而不管我调用哪个.php
文件。不过我可以想象,如果PHP在Web服务器环境中运行,那么该环境会将当前工作目录初始化为入口.php
文件。在macOS上使用通过Homebrew安装的PHP 7.2.2进行测试。 - herzbubeinclude
将按以下方式搜索它。首先,它将通过环境变量include_path
的路径进行搜索,该变量可以使用ini_set
设置。如果失败,则会在调用脚本自己的目录dirname(__FILE__)
(php >= 5.3时为__DIR__
)中搜索。如果这也失败了,那么它才会在工作目录中搜索!事实证明,默认情况下,环境变量include_path
以 .
开头,即当前工作目录。这就是为什么它首先在当前工作目录中搜索的唯一原因。请参见http://php.net/manual/en/function.include.php。
所以,第一个问题的正确答案是包含调用脚本的位置很重要。对于最后一个问题,初始工作目录在Web服务器上下文中是被PHP处理时包含所有其他脚本的脚本所在的目录。在命令行上下文中,初始工作目录是在提示符处调用php时的任何目录,不一定是调用脚本所在的目录。然而,当前工作目录可以使用PHP函数基于给定的文件路径或指定的
include_path
,包含文件。如果在include_path
中找不到文件,则在调用脚本自己的目录和当前工作目录中进行最后检查,然后失败。
chdir
在运行时更改。请参见http://php.net/manual/en/function.chdir.php。include_path
不够健壮,因此最好使用完整路径,例如./path
或__DIR__ . /path
。有些人甚至说依赖于工作目录.
本身并不安全,因为它可以被更改。然而,有时候你需要依赖环境值。例如,你可能想将include_path
设置为空,这样调用脚本的目录就是它首先搜索的地方,甚至在当前工作目录之前。代码可能已经编写并定期从外部源更新,你不想每次更新代码时都重新插入前缀__DIR__
。dirname(__FILE__)
(__DIR__)
中搜索(要求 PHP 版本 >= 5.3)。你确定吗?这在哪里有记录?我希望你是错的,PHP 不会为了这个目的使用 __FILE__
和 __DIR__
,因为这会立即破坏从符号链接中包含“同级”脚本! :-o (幸运的是,在我的 7.1 设置中,这似乎可以正常工作。) - Sz.include("./inc.php")
,那么将找到 /app/inc.php。
./ 不是必需的,但可以消除对include_path的依赖。chdir()
更改它。./
开头的字符串,它会首先检查调用脚本的目录还是当前工作目录? - Pacerier./
开头,则已经依赖于当前工作目录。例如,chdir("/app/other") 将使 include("./inc.php")
失败。因此,在这种情况下,请使用 include("inc.php")
以确保安全。 - Johnny Wongdir
-> a.php
-> c.php
- dir2
-> b.php
如果要在b
中包含a
,则需要使用include("../a.php");
如果要在c
中包含b
,则需要使用include("dir2/b.php");