SPL自动加载最佳实践

时间:2009-11-11 08:30:22

标签: php spl autoloader spl-autoloader

在服务器端的include_path中,我在'/ usr / share / pear /'中引用了一个pear目录。在我的应用程序中,我包含来自公共库的文件,位于带有require_once 'library/file.php'的'/ usr / share / pear / library /'中。

我最近开始使用spl自动加载器,我注意到在加载器函数中你必须确定包含文件的逻辑。我这样做的第一种方法是尝试包含一个文件并使用@来抑制它,以查看它是否会失败,例如: @include 'library/file.php'但我认为主要是因为我读了很多关于@是一种不好的做法我决定通过get_include_path爆炸PATH_SEPARATOR来自己手动完成工作,看看是否目录是我想要的,然后做file_exists并包含它。

像这样:

function classLoader( $class ) {
    $paths = explode( PATH_SEPARATOR, get_include_path() );
    $file = SITE_PATH . 'classes' . DS . $class . '.Class.php';
    if ( file_exists( $file) == false ) 
    {
        $exists = false;
        foreach ( $paths as $path ) 
        {
            $tmp = $path . DS . 'library' . DS . 'classes' . DS . $class . '.Class.php';
            if ( file_exists ( $tmp ) ) 
            {
            $exists = true;
            $file = $tmp;
            }
        }
        if ( !$exists ) { return false; }
    }
    include $file;
}

spl_autoload_register('classLoader');

我走错了路吗?我应该刚刚完成@include业务还是我在正确的方向上做了一些事情?

2 个答案:

答案 0 :(得分:6)

Habari project autoloader有趣的一件事就是将整个类文件列表缓存在内存中,这样每次请求类时都不会对文件进行磁盘搜索。

基本上,你在__autoload()中声明一个静态,它包含所有类文件的数组,由类引导它们加载。例如,代码将使用Dir或glob()生成此静态数组:

$class_files = array(
  'user' => '/var/www/htdocs/system/classes/user.class.php',
);

然后,您只需添加$class_files[$class]即可获取正确的文件。这很好而且快速,因为它一次从磁盘获取目录,而不是每次引用新类时生成列表或搜索特定文件名。 (你会惊讶于它产生了多大的速度差异。)

如果类名不是数组中的键,则可以抛出自定义异常或生成要返回的存根/模拟类。此外,如果您查看Habari系统自动加载器,您会看到Habari在自动加载的类中实现__static(),这就像静态类的构造函数。

应避免使用

include_once(),如果您已检查要包含的文件,则不需要@运算符。

答案 1 :(得分:1)

我个人使用

function autoload($class) {
    /* transform class name into filename ... */
    include $class;
}

即使没有@来简化调试(错误在生产中关闭/记录)

您可能也对PHP开发人员列表中的相关讨论感兴趣:http://marc.info/?t=125787162200003&r=1&w=2