SPL自动加载最佳实践

5
在服务器端的include_path中,我有一个对pear目录的引用,即'/usr/share/pear/'。在我的应用程序中,我从一个公共库中包含文件,位于'/usr/share/pear/library/'中,使用require_once 'library/file.php'
我最近开始使用spl自动加载器,我注意到在加载器函数中,您必须确定包含文件的逻辑。我第一次尝试的方法是尝试包含一个文件,并使用@来阻止错误,例如:@include 'library/file.php',但我认为这样做主要是因为我读了很多有关@是一个糟糕做法的文章,所以我决定手动处理工作,通过将get_include_pathPATH_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个回答

7

有一个有趣的功能是,Habari项目自动加载器会将整个类文件列表缓存在内存中,以便每次请求类时不必进行磁盘搜索。

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

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

然后你只需包含$class_files[$class]以获取正确的文件。这很好而且快速,因为它一次性从磁盘获取目录,而不是每次引用新类时生成列表或搜索特定文件名。(您会惊讶于它带来的速度差异。)
如果类名不是数组中的键,则可以抛出自定义异常或生成存根/模拟类进行返回。此外,如果查看Habari系统自动加载程序,您将看到Habari在自动加载的类中实现了__static(),这类似于静态类的构造函数。
应避免使用include_once(),如果您已经检查了要包含的文件,则不需要使用@运算符。

1

我个人采用的方式是

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

即使没有@符号也可以方便调试(错误会在生产环境中关闭/记录)。
您可能还对PHP开发者列表上的相关讨论感兴趣:http://marc.info/?t=125787162200003&r=1&w=2

3
自动加载是不是更实用、现代的方法?或者它们基本上是相同的东西? - meder omuraliev

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接