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


111

我在理解有关PHP相对包含路径的规则集时遇到了麻烦。如果我运行文件A.PHP-,文件A.PHP包含文件B.PHP,其中文件C.PHP,则C.PHP的相对路径应该与B.PHP的位置有关,还是与A的位置有关? .PHP?也就是说,从哪个文件调用include或仅从当前工作目录是什么以及确定当前工作目录的因素有关系吗?


我认为比接受的答案更准确:stackoverflow.com/a/23902890/1636522
树叶

Answers:


132

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

也就是说,从哪个文件调用include没关系

没有。

如果要使其变得重要,并相对于B.php进行包含,请使用__FILE__常量(或__DIR__自PHP 5.2 IIRC起),该常量将始终指向代码行所在的当前文字文件。

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

@Pekka-太棒了-正是我想要的。有关更多信息,请参见stackoverflow.com/questions/2184810/…–
Yarin

7
您也可以将其__DIR__用于确切的目的。
尼克·贝德福德

1
这个答案有点矫kill过正:不需要include(dirname(__FILE__)."/C.PHP");,因为include("C.PHP");足够了(是的!C.PHP可以和B.PHP放在同一个目录中)仅当项目中有两个C.PHP文件时,它才会失败。
Johnny Wong

更明确地说:如果包含路径中没有前缀“ ./”或“ ../”,则它相对于B.php和A.php。请参阅下面的答案。
Johnny Wong

21

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

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

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

使用这两个功能,您始终可以根据需要构建一个包含路径。

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

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

无论从哪里调用b.php。

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

资料来源:

getcwd()和dirname(__ FILE__)之间的区别?我应该使用哪个?

为什么要使用目录名(__FILE__)


我想添加一些内容,我有一个名为csb.php的文件,包括一个文件夹中的功能文件,而该功能文件包括与该功能文件相同的文件夹中的名为t.php的文件,当我尝试包含一个从文件夹t.php中名为csb.php的文件开始,它开始包含与调用函数文件相同的csb.php,但是当我将第二个csb.php更改为csbe.php时,它立即开始工作。因此,它似乎优先处理第一个文件夹,然后优先处理第二个包含文件夹!
米格尔·维埃拉

18
  1. 如果包含路径不是以./或开头../,例如:

    include 'C.php'; // precedence: include_path (which include '.' at first),
                     // then path of current `.php` file (i.e. `B.php`), then `.`.
  2. 如果包含路径以./或开头../,例如:

    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,然后如果包含中没有前缀“ ./”或“ ../”,则搜索B.php的路径。(假定使用默认的PHP设置)
Johnny Wong

感谢您引导我使用chdir(__DIR__)来解决问题。
哈特利圣山市,2013年

[...] getcwd(),默认为条目.php文件的路径[...] -不一定为true。如果我在命令行上运行PHP getcwd(),则无论.php我调用哪个文件,都引用该Shell的当前工作目录。但是,我可以想象,如果PHP在Web服务器环境中运行,则该环境会将当前的工作目录初始化为条目.php文件。在通过Homebrew安装的PHP 7.2.2的macOS上进行了测试。
herzbube18年

17

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

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

根据给定的文件路径包含文件,如果没有给出文件路径,则基于指定的include_path。如果在include_path中找不到该文件,则include最终将在失败之前检入调用脚本的自身目录和当前工作目录。

因此,对问题第一部分的正确答案是,所包含的调用脚本的位置确实很重要。问题的最后一部分的答案是,在Web服务器上下文中,初始工作目录是被调用脚本的目录,该脚本包括所有其他由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并没有使用__FILE____DIR__这个目的,因为这将打破迅速包括“兄弟”的脚本符号链接的!:-o(幸运的是,在我的7.1设置上,这里似乎工作正常。)
Sz。

6

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

TFM正确解释了这一点:

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

因此,如果/app/main.php表示include("./inc.php")将找到/app/inc.php

./不是绝对必要的,但消除了对包含路径的任何依赖。

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


因此,如果您以开头的字符串./,它是先检查调用脚本的目录还是首先检查当前工作目录?
Pacerier,2015年

2
@Denis Howe不,如果您的包含路径以开头,则您已经依赖于当前工作目录./。即chdir(“ / app / other”)将include("./inc.php")失败。因此,include("inc.php")在这种情况下使用是安全的。
Johnny Wong

@Pacerier如果字符串以./或../开头,则仅检查当前工作目录。(include_path和调用脚本的目录(B.php)都将被忽略)。请参阅我的答案以获取更多详细信息。
Johnny Wong

-2
dir
-> a.php
-> c.php

- dir2 
-> b.php

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

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


4
@Olli-您遗漏了问题的要点-我在问,当include链接时如何确定相对路径。
Yarin
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.