spl自动加载寄存器错误

时间:2018-06-25 16:26:31

标签: php spl-autoload-register

我正在编写一些我想使用spl_autoloader_register()函数加载的类。我创建了一个名为autoloader.php的文件,并将其保存在文件夹中,其中保存了项目所需的所有类。 因此,要验证其是否有效,我已在测试php页面中使用require_once加载了该文件,但不幸的是控制台日志向我显示了一个错误输出PHP Warning: include_once(lib\DataManager.php): failed to open stream: No such file or directory

测试文件位于承载所有类的同一文件夹内,是否由于这种动机而导致此错误?

这是自动加载器的代码

<?php 
function autoloader($className){
    include_once($className . '.php');
}

spl_autoload_register('autoloader');

?>

这是我尝试从测试页实例化它的方式

<?php

require_once 'autoloader.php';
require_once 'config.php';

use lib\DataManager as DataManager;

$dataManager = new DataManager($db);

?>

2 个答案:

答案 0 :(得分:0)

您几乎完全正确。问题是因为它没有指向正确的本地文件系统来查找文件。以下自动装带器将与相对插件模型和库文件夹模型一起使用。这将假定您在配置文件上定义了变量$GLOBALS['config']->lib,该变量定义了可能包含额外系统库的文件系统文件夹。当然,这可以有不同的定义,这取决于应用程序。

<?php 
function autoloader($className){
    $paths=[getcwd(),$GLOBALS['config']->lib];
    foreach($paths as $p){
        $filename = str_replace('\\','/',$p.'/'.$className.'.php');
        if (is_readable($filename)) {
            require_once($filename);
            return;
        }
    }
}
spl_autoload_register('autoloader');
?>

这将在考虑两种情况下工作,如果没有尝试使用类的预定义文件夹,则class是相对于最后请求的脚本的。找到并加载后,它应该返回,以避免继续尝试加载其他路径。

在数组上可以定义更多尝试路径,但是出于性能原因,请尝试使其不保留四个路径。同样,路径的顺序也是优先考虑的地方。

此脚本应在PHP 5.4及更高版本上运行。

答案 1 :(得分:0)

相对路径不是相对于它们所写入的文件来处理的,而是相对于PHP进程的“当前工作目录”(通常是Web进程的文档根目录,但不值得依赖)进行处理。

要引用当前源文件的位置,PHP提供了两个magic constants

  • __FILE__是您在其中写入任何源文件的标准文件名
  • __DIR__是包含该文件的目录

因此,假设您的类与自动加载器函数的定义位于同一目录中,则可以这样编写:

function autoloader($className){
    include_once __DIR__ . DIRECTORY_SEPARATOR . $className . '.php';
}

__DIR__在编译函数时被解析一次,因此无论何时运行此函数,它将始终引用定义此函数的目录,无论它在何处被调用,或者脚本的运行方式。

(请注意,includerequireinclude_oncerequire_once是不是函数的关键字,不需要在方括号内括起来。通常添加它们,但在某些情况下会引起混淆,因此最好避免。)