8

我正在开发自定义框架。当我试图让我的班级充满活力时,我遇到了一个问题。

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

在此处输入图像描述

所以我决定为每个文件夹(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');

尽管如此,我还是收到了这条消息:警告:require(libs/admin.php): failed to open stream,当然这不是好文件夹。但我不知道如何解决这个问题。有没有优化我的课程调用的好方法?

4

6 回答 6

12

经过几次测试,我为我的案例找到了这个解决方案:

set_include_path(implode(PATH_SEPARATOR, array(get_include_path(), './libs', './controllers', './models')));
spl_autoload_register();
于 2012-10-17T17:15:32.283 回答
5

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

使用 时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.

于 2012-10-16T11:59:38.077 回答
5

如果您有多个spl_autoload_register调用,则需要确保不使用require关键字来包含文件,因为这意味着“包含文件或如果不能就死”

就我个人而言,我不同意其他人关于只有一个自动加载功能的观点,特别是如果您包含来自不同位置的类,例如控制器与某些库目录。我还先检查文件是否存在,然后包含它。

tl;dr 版本:不允许spl_autoload_register呼叫相互阻止。

于 2012-10-16T12:09:12.117 回答
3

你的答案就在这里。当您注册多个自动加载器时,php 尝试通过这些自动加载器中的任何一个加载一个类,然后,php 从第一个注册到最后一个调用这些自动加载器。 然后,在这些自动加载器中的任何一个中,您都应该检查 file_exists 是否存在,否则,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;
}
于 2016-10-26T08:55:30.563 回答
1

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

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

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

于 2012-10-16T12:01:09.147 回答
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

于 2014-04-08T11:49:32.633 回答