包括未通过 require_once() 找到的文件

includes files not being found through require_once()

大家好,在开始我的问题之前,我要贴一张我的文件夹结构的照片,这样更容易看得见。

好的,在上面突出显示的 header.php 中,我有这行代码:

<?php require_once("admin/admin_pages/includes/init.php"); ?>

在那个 init.php 文件中:

<?php
require_once("functions.php");
require_once("db_config.php");
require_once("database.php");
require_once("user.php");
require_once("session.php");
require_once("photo.php");
require_once("db_object.php");
?>

但是,当我尝试打开位于我的根目录中的 index.php 文件时,出现此错误:

正在 required_once 的 init.php 正在运行。但是,它似乎没有找到 init.php 文件本身所需的文件(与 init.php 在同一目录中)。为什么会这样?

注意:当我在我的 admin/admin_pages/index.php 页面中游玩时,所有路径都有效。

编辑:这是我的包含文件夹中内容的屏幕截图。

<?php
//Just in case an includes file is not called in the init.php file.
function classAutoloader($class)
{
    $class = strtolower($class);
    $path = "includes/{$class}.php";

    if (file_exists($path)) {
        require_once($path);
    } else {
        die("The file named {$class}.php was not found.");
    }
}

spl_autoload_register('classAutoloader');

function redirect($location)
{
    header("Location: {$location}");
}
?>

编辑:这就是给出错误消息的原因,仅供参考。我已经设置了一个自动加载器功能。但是,该文件并没有丢失,应该以任何一种方式加载。

编辑:

由于您进行了一些编辑,其中您向我们展示了自动加载器的存在,我已经重新阅读了您的问题。跳出来的两个重要的东西:

  1. 此问题出现在您的 index.php 网站根目录中。
  2. 打印的错误源自 classAutoloader()
  3. (您对 admin/admin_pages/index.php 没有任何问题。)

看来还是跟下面说的一样的路径问题。当从 ~/index.php 调用自动加载器时,它会检查您的根目录是否包含 includes/db_object.php,但事实并非如此。

您可以通过指定相对于自动加载器文件的包含文件夹的路径来解决此问题,如下所示:

$path = __DIR__ ."/path/to/includes/{$class}.php";

虽然我没有看到这个解决方案有任何问题,但它对我来说看起来不是很优雅。或者,您可以指定从根目录开始的路径。


您的 init.php 文件有问题。

通过要求 admin/admin_pages/includes/init.php,您可以从需要它的文件中 运行 init.php 中的代码。如果这是有道理的。您可以在 header.php 中编写以下内容,它的行为与要求 init.php:

相同
<?php
require_once("functions.php");
require_once("db_config.php");
require_once("database.php");
require_once("user.php");
require_once("session.php");
require_once("photo.php");
require_once("db_object.php");
?>

您可能会注意到这没有意义,因为从 header.php 调用时这些路径不正确。您可以使用 __DIR__ 常量来解决此问题:

The directory of the file. If used inside an include, the directory of the included file is returned. This is equivalent to dirname(FILE). This directory name does not have a trailing slash unless it is the root directory. ~ The Manual


根据上述信息,您可能会自己弄清楚,但为了使我的回答完整,请将 init.php 中的代码更改为:

<?php
require_once __DIR__ . "/functions.php";
require_once __DIR__ . "/db_config.php";
require_once __DIR__ . "/database.php";
require_once __DIR__ . "/user.php";
require_once __DIR__ . "/session.php";
require_once __DIR__ . "/photo.php";
require_once __DIR__ . "/db_object.php";
?>

注意:

  1. require_once 不是一个函数而是一个语句,所以你这样称呼它。 requireincludeinclude_once.
  2. 也是如此
  3. 根据你的问题,只有 db_object.php 的要求失败了......这似乎有点奇怪。

Pro-tip(如 AnyhonyB 评论中所述):

One of the biggest annoyances is having to write a long list of needed includes at the beginning of each script (one for each class).

In PHP 5, this is no longer necessary. The spl_autoload_register() function registers any number of autoloaders, enabling for classes and interfaces to be automatically loaded if they are currently not defined. By registering autoloaders, PHP is given a last chance to load the class or interface before it fails with an error. ~ The Manual

大家好,谢谢大家的意见。我终于发现了我的代码的问题。不是因为autoloader功能。

我不知道 init.php 中调用文件的顺序很重要。我只是重新排序了 require_once() 语句。

db_object.php 文件实际上是包含我的对象(照片和用户)的父 class 的文件。 photo.phpusers.php 包含继承自 db_object.php 的 class。这对于我们为什么需要首先找到 db_object.php 是有道理的。

之前:

<?php
require_once("functions.php");
require_once("db_config.php");
require_once("database.php");
require_once("user.php");
require_once("session.php");
require_once("photo.php");
require_once("db_object.php");
?>

之后:

<?php
require_once("functions.php");
require_once("db_config.php");
require_once("database.php");
require_once("db_object.php");
require_once("user.php");
require_once("session.php");
require_once("photo.php");
?>

这不是答案,但可能有帮助:

考虑以下因素。

如果我们在同一个目录下有三个文件:

a.php:

<?php
require_once 'b.php';
require_once 'c.php';

b.php:

<?php
class B extends C
{}

c.php:

<?php
class C
{}

如果我 运行 a.php 我得到这个输出:

 Fatal error: Class 'C' not found in /var/www/Whosebug/req_test2/b.php on line 3

这表明顺序对 require 调用很重要。

如果我将 a.php 的内容换成下面的 运行 它:

<?php
spl_autoload_register();

$b = new B;
var_dump($b);

我得到这个输出:

object(B)#1 (0) {
}

spl_autoload_register() 这里不带参数使用 spl_autoload() 的默认实现:对名为 Foo 的 class 的引用,将查找包含文件 foo.php 来自您的包含路径。

此处 B 的初始化引用 class C,上面的自动加载器将负责根据需要请求适当的文件。

我建议将每个 class 定义放在一个单独的文件中。使用文件名到 class 的一对一映射。您可能还对 PSR-4 样式感兴趣。

尽早申报自动装弹机。也可以预先包含实用函数。

您的代码的修复方法是将您的 includes 文件夹添加到您的 include 路径,并将您的 require 行更改为 $path = "{$class}.php";。我会亲自移除自动加载器中的模具线,因为您可能需要注册多个自动加载器 - 这些都是可堆叠的,就像您的包含路径一样。

把db_object.php文件放在init.php文件中users.php文件上面,就可以找到了。我正在学习同一门课程,这就是解决方案