spl_autoload_register() 在不同的目录

Posted

技术标签:

【中文标题】spl_autoload_register() 在不同的目录【英文标题】:spl_autoload_register() in different directories 【发布时间】:2014-09-03 06:05:00 【问题描述】:

我有一个文件可以自动加载我的每个类。 这是它包含的内容:

spl_autoload_register(function($class)
    require_once 'classes/' . $class . '.php';
);
require_once 'functions/sanitize.php';
require_once 'functions/hash.php';

但是当我 require_once 这个文件来自我的 ajax 文件夹中的另一个 php 文件时,它会尝试查找 classes,该函数将从我的具有路径的类:main_folder/ajax/classes 而不仅仅是 main_folder/classes

有谁知道如何解决这个问题?

修复

spl_autoload_register(function($class)
    if (file_exists('classes/' . $class . '.php')) 
       require_once 'classes/' . $class . '.php';
    
    elseif (file_exists('../classes/' . $class . '.php')) 
       require_once '../classes/' . $class . '.php';
    
    elseif (file_exists('../../classes/' . $class . '.php')) 
       require_once '../../classes/' . $class . '.php';
    

【问题讨论】:

【参考方案1】:

您应该只在主文件(通常是 index.php)中使用此函数一次,而不是在其他文件中。

但是,如果不可能(但我看不出有什么理由什么时候不可能),你可以改变它,例如:

spl_autoload_register(function($class)
    if (file_exists('classes/' . $class . '.php')) 
       require_once 'classes/' . $class . '.php';
    
    elseif (file_exists( $class . '.php')) 
       require_once $class . '.php';
    
);

【讨论】:

是的,但问题是我将所有 php ajax 文件保存在单独的目录中。因此,即使我在 index.php 中调用此函数,它也不起作用,因为我通过 jQuery 拉动我的 Ajax。你提供的代码还能用吗? 如果你把这段代码放到AJAX目录下,你应该简单的添加/更改规则。在上面的代码中,类首先在classes 目录中进行检查,如果它们不存在,则在当前目录中进行检查。因此,如果您在 ajax 目录中有类,并且您运行将此自动加载器添加到 ajax 目录中的其他文件中,它也应该从 ajax 目录加载文件而没有问题 哦,我明白了,聪明的想法,我所要做的就是:`elseif (file_exists('../classes/' . $class . '.php')) require_once '。 ./classes/' . $类。 '.php'; 【参考方案2】:

这是一个正确的方法,它应该普遍有效。

编辑:确保在dirname 上指定级别,以便找到正确的路径。

spl_autoload_register(function ($classname) 
    $file_realpath = dirname(realpath(__FILE__), levels: 1 /* Change that? */) . DIRECTORY_SEPARATOR . dirname($classname);
    $classpath = sprintf('%s' . DIRECTORY_SEPARATOR . '%s.php', $file_realpath, basename($classname, '.php,PHP'));

    if (file_exists($classpath)) 
        echo "Loading <b>$classpath</b>...<br>";
        require($classpath);
    
);

【讨论】:

【参考方案3】:

您需要知道 classes 目录的绝对路径,然后只需使用完整的限定路径即可。

确保您的文档根目录已正确配置您的 http 服务器。此外,这通常通过将所有请求路由到 index.php 并从那里派生基本路径(文档根)来解决。这是您修改的代码:

spl_autoload_register(function($class) 
    $resolved = $_SERVER['DOCUMENT_ROOT'] . DIRECTORY_SEPARATOR . 'classes' . DIRECTORY_SEPARATOR . $class . '.php';
    if(file_exists($resolved)) 
      require_once $resolved;
     else 
      // make it known to your that a class failed to load somehow
      return;
    
)

这是我用于简单项目的另一种实现

【讨论】:

您的解决方案看起来很完美,但它不起作用...我检查了我的项目根目录,一切看起来都很好。有其他想法吗? 文档根目录的完整路径? 是的。奇怪的是,当它指示的路径是正确的路径时,我得到了这个错误:Failed opening required 'C:/wamp/www/functions/sanitize.php' (include_path='.;C:\php\pear') in C:\wamp\www\JamsRecord\coding\core\app_loader.php on line 12 你使用的是windows,所以目录分隔符需要是反斜杠 试试新的编辑。另外,告诉我你的调用代码失败的地方。

以上是关于spl_autoload_register() 在不同的目录的主要内容,如果未能解决你的问题,请参考以下文章

PHP中spl_autoload_register函数的用法

spl_autoload_register与autoload的区别详解

spl_autoload_register 和 __autoload()魔术方法

php spl_autoload_register() 函数

php spl_autoload_register()不加载类

转详解spl_autoload_register()函数