多个spl_autoload_register问题

时间:2012-10-16 11:58:14

标签: php class spl-autoload-register

我正在开发自定义框架。 当我试图动员我的课程时,我遇到了一个问题。

这是我的文件的视觉效果:

enter image description here

所以我决定为每个文件夹(libs,controllers et modeles)创建一个不同的函数:

function autoloadLibs($class) {
    //require the general classes
    require 'libs/' . $class . '.php';
}

function autoloadModels($class) {
    //require the models classes
    require 'models/' . $class . '.php';
}

function autoloadControllers($class) {
    //require the controllers classes
    require 'controllers/' . $class . '.php';
}

spl_autoload_register ('autoloadLibs');
spl_autoload_register ('autoloadControllers');  
spl_autoload_register ('autoloadModels');

尽管如此,我有这样的信息:警告:要求(libs / admin.php):无法打开流,对于cours来说这不是好文件夹。但我不知道如何解决这个问题。有没有一种优化我的类调用的好方法?

6 个答案:

答案 0 :(得分:11)

经过几次测试,我找到了适合我案例的解决方案:

set_include_path(implode(PATH_SEPARATOR, array(get_include_path(), './libs', './controllers', './models')));
spl_autoload_register();

答案 1 :(得分:5)

在尝试require之前,您需要先使用is_file()检查该文件是否存在。

使用spl_autoload_register()时,我发现注册一个方法以包含文件通常会更好。您可以使用多个函数来实现这一事实,即可以轻松实现与不同库的互操作性(因此它们不会破坏__autoload())。它还可以节省您多次编写代码以检查文件是否存在,将_映射到目录分隔符(如果您这样做)等等。

因此,假设您更改的文件名符合Underscore_Separated_Name的约定,例如Controller_Admin_Dashboard,你可以使用......

function autoload($className) {

    $path = SYSPATH .
            str_replace("_", DIRECTORY_SEPARATOR, strtolower($className)) . 
            ".php";

    if (is_file($path)) {
        require $path;
    }

}

第一次实例化Controller_Admin_Dashboard时,PHP可能包含/app/controller/admin/dashboard.php等文件。

答案 2 :(得分:4)

如果您有多个spl_autoload_register来电,则需要确保不使用require关键字来包含这些文件,因为这意味着“包含该文件或者如果可以,则会死亡“T“即可。

我个人不同意其他人只有一个自动加载功能,特别是如果你包括来自不同位置的类,比如控制器和某些库目录。我还检查文件是否存在,然后包含它。

tl; dr版本:不允许spl_autoload_register来电相互阻止。

答案 3 :(得分:3)

你的答案就在这里。 当你注册多个自动加载器时,php尝试加载任何一个自动加载器的类,然后,php从第一个注册到最后一个调用那些自动加载器。     然后,在任何一个自动加载器中你应该检查file_exists, else ,php尝试包含它并在该文件不存在时抛出错误。 然后,在加入之前,检查文件的存在。 将自动加载器更改为:

function autoloadLibs($class)
{
  #require the general classes
  $file = 'libs/' . $class . '.php';
  if(file_exists($file))
    require $file;
}

function autoloadModels($class)
{
  #require the models classes
  $file = 'models/' . $class . '.php';
  if(file_exists($file))
    require $file;
}

function autoloadControllers($class)
{
  #require the controllers classes
  $file = 'controllers/' . $class . '.php';
  if(file_exists($file))
    require $file;
}

答案 4 :(得分:1)

您应该在需要文件之前检查类名,例如:

function autoloadControllers($class) {
    //require the controllers classes
    if( substr( $class, -10) == 'Controller')){
        require 'controllers/' . $class . '.php';
    }
}

如果无法加载类,我发现导致错误是正确的,但是您应确保仅在正确的路径上调用require

答案 5 :(得分:1)

请注意,spl_autoload_register提供了第三个参数(prepend)。如果您希望在自动加载堆栈顶部放置特定的自动加载功能,可以将其设置为true。这意味着将首先调用此特定函数。

示例:

  

spl_autoload_register(array('My_Class','My_Method'),true,true);

http://www.php.net/manual/en/function.spl-autoload-register.php