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业务,还是我在某种程度上朝着正确的方向做这件事?

4

2 回答 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()是要避免的,@如果您检查了要包含的文件,则不需要操作符。

于 2009-11-11T19:25:48.663 回答
1

我个人使用

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

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

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

于 2009-11-11T08:42:47.683 回答