require_once 中包含路径解析如何工作?

发布于 2024-08-16 10:08:31 字数 1283 浏览 2 评论 0原文

我正在用 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我看到了这个问题,但它仍然没有回答我在这里所说的第二种情况。

I was writing an web app in PHP, when I encountered a strange situation. To illustrate my problem, consider a web app of this structure:

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

Contents of these files:

index.php:

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

f1.php:

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

f2.php: blank

now when I try to open index.php in my browser I get this error:

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

Is there something obvious I'm missing? how do include paths work in PHP?


Before I asked this question, I attempted to experiment and find out. I set up another test, like so:

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

index.php:

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

f1.php:

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

f2.php: blank

To my surprise (and utter confusion), this worked out fine!

So, what is the secret behind the path resolution?

PS I saw this question, but it still does not answer the second case that I've stated here.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

毁梦 2024-08-23 10:08:31

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

您的示例正在按预期工作。

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

编辑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' 可以工作并且 require 不会失败。

If you include another file, the working directory remains where the including file is.

Your examples are working as intended.

Edit: The second example works because . (actual directory) is in your include path (see your error message).

Edit2:
In your second example, the key point of your interest is this line:

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

At first it will look in the current working dir (/var/www/req_path_test), but does not find f2.php.

As fallback, it will try to find f2.php in your include_path ('.:/usr/share/php:/usr/share/pear'), starting with '.' (which is relative to the actual file, not the including one).

So './f2.php' works and the require does not fail.

小苏打饼 2024-08-23 10:08:31

当您打开index.php时,工作目录将设置为该文件所在的文件夹。并且在包含的f1.php中,该工作目录不会更改。

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

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

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

When you open index.php, working dir is set to the folder this file resides in. And inside insluded f1.php this working dir does not change.

You can include files by using their absolute paths, relative to the current included file like this:

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

But better consider using an autoloader if these files contain classes.

云淡风轻 2024-08-23 10:08:31

通常在旧结构中

而不是

应该可以工作。据我所知 php 从初始脚本获取路径

Normaly in you old structure

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

instead of

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

should work. As far as i know php takes the paths from the initial script

舟遥客 2024-08-23 10:08:31

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

It sounds like your server has the open_basedir setting enabled in the PHP configuration. This makes it impossible to include (and open) files in folders above your in the directory structur (i.e., you can't use ../ to go up in the folder structure).

你的心境我的脸 2024-08-23 10:08:31

来自 PHP 文档 PHP include

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

如果未给出文件路径,则即 require_once("f2.php");

第一。 第二次检查 include_path

。 第三步检查调用脚本自己的目录

。最后检查当前工作目录

如果未找到文件,则 PHP 会在文件 include & 上抛出警告。需要致命错误

如果定义了路径 - 无论是绝对路径(在 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. 这次您 require("f2.php") 没有前导 ../ 或 ./ 这次 PHP 检查 include_path 但确实在那里找到了它,因为您还没有定义它并且该文件不驻留在默认预设 include_path。
  2. 这次调用脚本f1.php的目录是f1/。并且您需要的文件(“f2.php”)位于此目录中。 PHP 这次检查这个目录下的文件,找到了。
  3. PHP 不必在找到文件时检查工作目录。

因此您的代码可以正常工作!

From the PHP Docs PHP include

Files are included based on the file path given or, if none is given, the include_path specified. If the file isn't found in the include_path, include will finally check in the calling script's own directory and the current working directory before failing.

If the file path is not given then i.e require_once("f2.php");

1st. The include_path is checked

2nd. The calling scripts own directory is checked

3rd. Finally the current working directory is checked

If file not found then PHP throws warning on file include & fatal error on require

If a path is defined — whether absolute (starting with a drive letter or \ on Windows, or / on Unix/Linux systems) or relative to the current directory (starting with . or ..) — the include_path will be ignored altogether. For example, if a filename begins with ../, the parser will look in the parent directory to find the requested file.

If you include/require your file beginning with . or .. or ./ then PHP's parser will look in the parent directory which is the current working directory i.e require_once("../f2/f2.php"), php will check at the root directory as the calling script index.php is in that directory.

Now You have not defined any include path in your PHP script thus it always falls back to the calling script and then into the current working directory.

// 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

The Current Working Directory is derived from your main calling script index.php.

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

In the first Example where the required file "../f2/f2.php" is from f1.php

You code does not work because -

  1. The specified path is ignored by PHP as your filename begins with ../
  2. f1/ the calling script's own directory is ignored as well.
  3. The parser directory looks into the parent directory to find the requested file. The current working directory is root directory, this is from where you have initiated the working script index.php. The file is not located at this directory, wrong path given.

Thus you get the Fatal Error

In the Second example you have changed the directory & from f1.php you require_once("f2.php").

Your code works because -

  1. This time you require("f2.php") no leading ../ or ./ This time PHP checks the include_path but does find it there, as you haven't defined it and the file does not reside in the default preset include_path.
  2. This time the calling script f1.php's directory is f1/. and you require file ("f2.php") is located at this directory. PHP This time checks the file in this directory and finds it.
  3. PHP does not have to check the working directory as the file was found.

Thus Your Code Works Fine!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文