PHP将包含一个相对于调用脚本的文件,但如果包含路径包含“../”则不会

时间:2013-03-16 20:33:22

标签: php include relative

我查看了很多与此问题相关的帖子,但没有找到任何可以解决这个问题的帖子......如果我错过了相关问题,我会道歉。

从我从PHP的文档和此处的其他帖子中收集到的内容,PHP的include(和include_once)执行以下操作:

  

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

我在给定目录中有以下结构:

  • 的index.php
  • / dirA(包含a.php和b.php)
  • / dirB(包含c.php)

来自index.php include_once "dirA/a.php"

这是a.php中的作用:
include_once "b.php"
include_once "dirB/c.php"

这是什么DOESN“T在a.php中起作用:
include_once "b.php"
include_once "../dirB/c.php"

对我来说好奇的是b.php是相对于“调用脚本自己的目录”而包含的,但是c.php仅被认为是相对于当前工作目录(它是包含index.php的目录)。这对我来说似乎有点不一致。 PHP将包含一个相对于调用脚本的文件,但如果包含路径包含../则不会 - 为什么? 为什么../父目录指令不会相对于调用脚本工作但是它相对于当前工作目录?(注意:我相对于cwd测试了它但没有在上面的例子中包含该文件只是为了让它更干净。它工作得很好)

任何人都可以解释为什么会这样吗? 它应该以这种方式工作,还是这个bug?

2 个答案:

答案 0 :(得分:2)

PHP在查找文件方面有点奇怪。如果您包含名称以斜杠或点开头的文件,PHP将完全忽略include_path。如果是一个点,它假定该名称是相对于启动所有内容的脚本(即:Web服务器决定运行的脚本)。

如果要指定相对于包含的脚本而不是启动脚本的路径,那么您真正想要的是一个绝对包含,它指定文件的全名。使用__FILE____DIR__常量很容易做到,这些常量反映了当前运行脚本的名称和目录。

include __DIR__ . '/../dirB/c.php';

如果您愿意,还可以将include_path配置设置设置为包含应用程序的根目录,并指定与之相关的所有文件名。

答案 1 :(得分:0)

这是因为您首先将dirA/a.php添加到index.php,因此从现在开始index.php是您的基本文件,所有包含文件都是从该文件开始的。因此,如果您在c.php中加入a.php,就好像是从index.php

进行的

如果您使用"../"指定一个级别,那么这就是您收到错误结果的原因。它会搜索index.php以上的某个级别,但却找不到任何内容。