Php 包含路径解析如何在require_中工作一次?

Php 包含路径解析如何在require_中工作一次?,php,include,include-path,require-once,Php,Include,Include Path,Require Once,我正在用PHP编写一个web应用程序,突然遇到了一个奇怪的情况。为了说明我的问题,考虑一下这种结构的Web应用程序: / index.php f1/ f1.php f2/ f2.php 这些文件的内容: index.php: <?php require_once("f1/f1.php"); ?> <?php require_once("f1/f1.php"); ?> 我有什么明显的遗漏吗?包含路径在PHP中是如

我正在用PHP编写一个web应用程序,突然遇到了一个奇怪的情况。为了说明我的问题,考虑一下这种结构的Web应用程序:

/
    index.php
    f1/
        f1.php
    f2/
        f2.php
这些文件的内容:

index.php:

<?php require_once("f1/f1.php"); ?>
<?php require_once("f1/f1.php"); ?>
我有什么明显的遗漏吗?包含路径在PHP中是如何工作的


在我问这个问题之前,我试图通过实验来找出答案。我设置了另一个测试,如下所示:

/
    index.php
    f1/
        f1.php
        f2.php
index.php:

<?php require_once("f1/f1.php"); ?>
<?php require_once("f1/f1.php"); ?>

f1.php:

<?php require_once("../f2/f2.php"); ?>
<?php require_once("f2.php"); ?>

f2.php:空白

令我惊讶的是(和完全的困惑),这个结果很好

那么,路径解析背后的秘密是什么


PS我看到了,但它仍然不能回答我在这里所说的第二种情况。

在你的旧结构中是正常的

而不是


应该有用。据我所知,当您打开index.php时,php采用初始脚本的路径,working dir设置为该文件所在的文件夹。在insludedF1.php中,这个工作目录不会改变

可以使用文件相对于当前包含的文件的绝对路径包含文件,如下所示:

require_once(dirname(__FILE__).'/../../test/file.php')

但如果这些文件包含类,最好考虑使用AutoLoad。

< P>听起来好像你的服务器在PHP配置中启用了设置。这使得无法在目录结构中包含(和打开)您上方文件夹中的文件(即,您不能使用../进入文件夹结构)。

如果包含另一个文件,工作目录将保留包含文件的位置

您的示例正在按预期工作

编辑:第二个示例之所以有效,是因为。(实际目录)位于包含路径中(请参阅错误消息)

Edit2: 在第二个示例中,您感兴趣的关键点是这一行:

<?php require_once("f2.php"); ?>

首先,它将查找当前工作目录(
/var/www/req\u path\u test
),但找不到f2.php

作为回退,它将尝试在include_路径(
'):/usr/share/php:/usr/share/pear'
)中查找f2.php,以“.”开头(相对于实际的文件,而不是包含的文件)

因此,“/f2.php”可以工作,并且require不会失败。

来自php文档

根据给定的文件路径包含文件,如果未给定,则根据指定的包含路径包含文件。如果在include_路径中找不到该文件,include将在失败之前最终签入调用脚本自己的目录和当前工作目录

如果没有给出文件路径,即require_once(“f2.php”)

第一。选中包含路径

第二。已选中调用脚本自己的目录

三,。最后检查当前工作目录

若并没有找到文件,那个么PHP会在文件include上抛出警告&在require上出现致命错误

如果定义了路径-无论是绝对路径(在Windows或/在Unix/Linux系统上以驱动器号或\开头)还是相对于当前目录(以.or..开头)-include_路径都将被完全忽略。例如,如果文件名以../开头,解析器将在父目录中查找请求的文件

如果您包括/需要以开头的文件。或或者./然后PHP的解析器将查找当前工作目录的父目录,即require_once(../f2/f2.PHP),PHP将在根目录检查调用脚本index.PHP所在的目录

现在您还没有在PHP脚本中定义任何包含路径,因此它总是返回到调用脚本,然后返回到当前工作目录

当前工作目录是从主调用脚本index.php派生的

在第一个示例中,所需文件“./f2/f2.php”来自f1.php

您的代码不起作用,因为-

  • 当文件名以..开头时,PHP将忽略指定的路径/
  • f1/调用脚本自己的目录也被忽略
  • 解析器目录查找父目录以查找请求的文件。当前工作目录是根目录,这是您启动工作脚本index.php的位置。文件不在此目录中,给出了错误的路径
  • 因此您会得到致命错误

    在第二个示例中,您已经更改了目录&从f1.php开始,您需要一次_(“f2.php”)

    你的代码之所以有效是因为——

  • 这一次您需要(“f2.php”)无前导../或/这一次php检查include_路径,但确实在那里找到了它,因为您尚未定义它,并且文件不位于默认预设的include_路径中
  • 这次调用脚本f1.php的目录是f1/。您需要文件(“f2.php”)位于这个目录中。PHP这次检查这个目录中的文件并找到它
  • PHP不必在找到文件时检查工作目录

  • 因此,您的代码运行良好

    我知道。我真正想知道的是为什么第二个案例没有失败。这不是一个问题,这是一个痒:)我已经绕过了这个问题(使用dirname)。我想知道的是为什么第二个案例没有失败。这是一个bug还是一个特性?编辑了我的答案以涵盖第二个示例。我找不到记录从f1.php成功调用require_once('f2.php')的手册页面。文档说,当没有提供路径信息时,include_path会被忽略(不管怎样,从include_path中删除“.”没有任何效果),getcwd()显示include链的所有工作目录都是相同的。说真的,它看起来像一个未记录的功能。有用文章:在我的服务器中,open_basedir设置没有“值”。这意味着什么?尝试添加'echo getcwd();'要查看脚本,当前工作目录如何更改以及是否更改。-这里的评论说,它的行为从PHP4变为PHP5。例如,我尝试了echo:
    // The Current Working Directory can be checked
    echo getcwd();