如何在require_once中包含路径解析?

问题描述 投票:16回答:5

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

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

这些文件的内容:

index.php文件:

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

f1.php:

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

f2.php:空白

现在当我尝试在浏览器中打开index.php时出现此错误:

Warning: require_once(../f2/f2.php) [function.require-once]: 
failed to open stream: No such file or directory in /var/www/reqtest/f1/f1.php on line 2
Fatal error: require_once() [function.require]: 
Failed opening required '../f2/f2.php' (include_path='.:/usr/share/php:/usr/share/pear') in /var/www/reqtest/f1/f1.php on line 2

有什么明显的东西我不见了吗?如何在PHP中包含路径?


在我提出这个问题之前,我试图尝试并找出答案。我设置了另一个测试,如下所示:

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

index.php文件:

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

f1.php:

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

f2.php:空白

令我惊讶的是(并且完全混乱),这很好!

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

PS我看到this question,但它仍然没有回答我在这里说过的第二个案例。

php include include-path require-once
5个回答
12
投票

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

您的示例按预期工作。

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

编辑2:在你的第二个例子中,你感兴趣的关键点是这一行:

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

首先它将查看当前工作目录(/var/www/req_path_test),但找不到f2.php。

作为后备,它会尝试在你的include_path('.:/usr/share/php:/usr/share/pear')中找到f2.php,以'。'开头。 (相对于实际文件,而不是包含的文件)。

所以'./f2.php'有效并且要求不会失败。


4
投票

当你打开index.php时,工作目录被设置为这个文件所在的文件夹。而在f1.php里面,这个工作目录不会改变。

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

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

但如果这些文件包含类,最好考虑使用自动加载器。


0
投票

Normaly在你的旧结构

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

代替

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

应该管用。据我所知,php从最初的脚本中获取路径


0
投票

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


0
投票

来自PHP Docs PHP include

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

如果没有给出文件路径,那就是require_once(“f2.php”);

1。 include_path被选中

第2位。调用脚本自己的目录

3。最后检查当前工作目录

如果找不到文件,则PHP会在文件包含上发出警告并在require上发生致命错误

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

如果您包含/要求您的文件开头。或..或./然后PHP的解析器将在父目录中查找当前工作目录,即require_once(“../ f2 / f2.php”),php将在根目录中检查为调用脚本index.php在那个目录中。

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

// Check your default include path, most likely to be C:\xampp\php\PEAR
echo get_include_path();

// To set include path
set_include_path ( string $new_include_path ) : string

当前工作目录源自主调用脚本index.php。

// The Current Working Directory can be checked
echo getcwd();

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

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

  1. PHP会忽略指定的路径,因为您的文件名以../开头
  2. f1 /调用脚本自己的目录也被忽略。
  3. 解析器目录查看父目录以查找请求的文件。当前工作目录是根目录,这是您发起工作脚本index.php的地方。该文件不在此目录中,给出了错误的路径。

因此,您会收到致命错误

在第二个示例中,您已经更改了目录&f1.php中的require_once(“f2.php”)。

您的代码有效,因为 -

  1. 这次你需要(“f2.php”)没有前导../或./这次PHP检查include_path但确实在那里找到它,因为你还没有定义它并且文件没有驻留在默认的预设include_path中。
  2. 这次调用脚本f1.php的目录是f1 /。并且您需要文件(“f2.php”)位于此目录中。 PHP这次检查此目录中的文件并找到它。
  3. 在找到文件时,PHP不必检查工作目录。

因此您的代码工作正常!

© www.soinside.com 2019 - 2024. All rights reserved.