如何使用 __autoload 从多个目录加载类? [英] How can I load classes from multiple directories with __autoload?

查看:19
本文介绍了如何使用 __autoload 从多个目录加载类?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

跟进这个问题,似乎重复的问题可能只需使用下面的 __autoload 代码即可解决,

Following up on this question, it seems that the duplicate issue could be solved by just using the __autoload code below,

function __autoload($class_name) 
{
    include AP_SITE."classes_1/class_".$class_name.".php";
}

$connection = new database_pdo(DSN,DB_USER,DB_PASS);
var_dump($connection);

结果,

object(database_pdo)[1]
  protected 'connection' => 
    object(PDO)[2]

但这只会从一个目录加载类,其他目录呢?因为我将类分组在不同的目录中.所以如果我想从其他目录加载类,我会得到错误,

but this only loads the classes from one directory, what about other directories? Because I group the classes in different directories. So I will get error if I want to load classes from other directories,

function __autoload($class_name) 
{
    include AP_SITE."classes_1/class_".$class_name.".php";
    include AP_SITE."classes_2/class_".$class_name.".php";
}

留言,

警告:包括(C:/wamp/www/art_on_your_doorstep_2011_MVC/global/applications/CART/classes_2/class_database_pdo.php)[function.include]:无法打开流:没有这样的文件或目录在...

Warning: include(C:/wamp/www/art_on_your_doorstep_2011_MVC/global/applications/CART/classes_2/class_database_pdo.php) [function.include]: failed to open stream: No such file or directory in ...

引用这一行 - include AP_SITE."classes_2/class_".$class_name.".php";

所以,我的问题是 - 如何使用 __autoload 从多个目录加载类?

So, my question is - how can I load classes from multiple directories with __autoload?

一个可能的解决方案:

function autoload_class_multiple_directory($class_name) 
{

    # List all the class directories in the array.
    $array_paths = array(
        'classes_1/', 
        'classes_2/'
    );

    # Count the total item in the array.
    $total_paths = count($array_paths);

    # Set the class file name.
    $file_name = 'class_'.strtolower($class_name).'.php';

    # Loop the array.
    for ($i = 0; $i < $total_paths; $i++) 
    {
        if(file_exists(AP_SITE.$array_paths[$i].$file_name)) 
        {
            include_once AP_SITE.$array_paths[$i].$file_name;
        } 
    }
}

spl_autoload_register('autoload_class_multiple_directory');

推荐答案

您可以使用 spl_autoload_register 注册多个自动加载功能 而不是单个 __autoload 函数.这是推荐的方式.

You can register multiple autoload functions by using spl_autoload_register instead of the single __autoload function. That's the recommended way.

如果一个自动加载器能够加载文件,则不会调用堆栈中的下一个.

If one autoloader was able to load the file, the next one in the stack won't be called.

然而,每个自动加载器应该只加载它的类,所以你需要通过类名和/或is_file来检查.按类名通常更好,因为如果您的应用程序增长,在文件系统上疯狂尝试会给系统带来压力.

Each autoloader however should only load the classes it is for, so you need to check that by the classname and/or with is_file. By classname often is better because trying wildly on the file-system can stress a system if your application grows.

为了不重新发明轮子,您甚至可以使用已经存在的自动加载器,它能够处理文件名调用的 PSR-0 标准.这些通常允许在基目录上注册特定的命名空间.在您的情况下,这意味着您必须根据 PSR-0 约定.

To not re-invent the wheel, you could even use an autoloader that already exists which is able to deal with the PSR-0 standard on file-name-calling. Those often allow to register a specific namespace on a base-directory. In your case that would mean that you must rename and organize your files according to the PSR-0 convention.

快速解决方案(与您的问题相关):

The quick solution (bound to your question):

function __autoload($class_name) 
{
    $file = sprintf('%sclasses_1/class_%s.php', AP_SITE, $class_name);
    if (is_file($file))
    {
        include $file;
        return;
    }
    $file = sprintf('%sclasses_2/class_%s.php', AP_SITE, $class_name);
    if (is_file($file))
    {
        include $file;
        return;
    }
}

如您所见,已经有重复的代码(如您的).因此,这应该只是一个临时解决方案,因为您最终会为要测试的每个目录生成越来越多的重复行.如果您考虑更改设计,请考虑 PSR-0 shema,它有助于简化代码库,并且可以轻松重用 PHP 世界中的其他现有组件.

As you can see, there is already code duplicated (as in yours). So this should just be a temporary solution as you will end up with more and more duplicated lines for each directory you would like to test for. If you consider to change the design, please take the PSR-0 shema into account, it helps to streamline one's codebase and makes it easy to re-use other existing compontents in the PHP world.

function autoload_class_multiple_directory($class_name) 
{

    # List all the class directories in the array.
    $array_paths = array(
        'classes_1/', 
        'classes_2/'
    );

    foreach($array_paths as $path)
    {
        $file = sprintf('%s%s/class_%s.php', AP_SITE, $path, $class_name);
        if(is_file($file)) 
        {
            include_once $file;
        } 

    }
}

spl_autoload_register('autoload_class_multiple_directory');

这篇关于如何使用 __autoload 从多个目录加载类?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆