【问题标题】:__autoload detecting and including interfaces__autoload 检测并包含接口
【发布时间】:2011-11-03 22:26:23
【问题描述】:

我在脚本中使用 __autoload 来根据需要包含类。我的脚本使用类名中的提示来查找包含它的文件。如果以model结尾,则在model目录中,controllers在controller目录中,等等。我开始实现接口,所以需要调整我的自动加载器。

理想情况下,当创建对象时,自动加载器将确定对象的文件名、存储位置并包含该文件。然后它会询问该类它实现了哪些接口,然后自动包含这些文件。

类似

function __autoload($classname){
    echo $classname;
    include ("classes/$classname.php");
    $interfaces = class_implements($classname,FALSE);
    foreach($interfaces as $name){
        if(!class_exists($name,FALSE)){
        include("interfaces/".$name."inter.php");
        }
    }
}

除非我这样做,否则我会收到错误

无法重新声明 __autoload()(之前在 W:\xampp\htdocs\test\auto.php:5) 在 W:\xampp\htdocs\test\auto.php 上 第 11 行

在 __autoload() 中不可能做到这一点吗?我是否应该继续依靠命名约定来区分对象类型和存储位置?

【问题讨论】:

标签: php interface autoload implements


【解决方案1】:

使用spl_autoload_register 注册额外的自动加载功能。您指定的自动加载函数是一个回调。这意味着您可以将方法或类方法传递给它。这样,您可以将额外的自动加载添加到您的各种类中,而不必担心命名冲突。

[编辑]

这种方式是行不通的。查看 KingCrunch 的聪明答案。

即使这样可行,我也建议不要这样做。通过使用单个自动加载功能,或者每个库或您使用的框架可能有额外的自动加载功能,您可以保持自动加载简单明了。添加额外的函数可能会使调试过于复杂。

【讨论】:

    【解决方案2】:

    由于您已经依赖于类的命名约定,只需修改现有的 __autoload 以解析接口名称。如果您将所有接口命名为“I_something”,这应该是一个简单的更改。

    如果您不想依赖命名约定,那么您需要设置某种类和接口注册表。注册表可以像硬编码数组一样简单,例如:

    function __autoload($classname) {
        $classlist=array('MyClass1','path/to/file/myclass1.php',
                              'MyClass2','path/to/file/foo.php',
    ...
                             );
    
        $interfacelist=array('MyInterface1','path/to/file/bar1.php',
                                  'I_foo','path/to/file/bibble.php',
    ...
                             );
                $path=$classname;
                if(array_key_exists($classname,$classlist)) {
                    $path=PATH_CLASSES.$classlist[$classname];
                } else if(array_key_exists($classname,$interfacelist)) {
                    $path=PATH_INTERFACES.$interfacelist[$classname];
                }
                if(file_exists($path)) {
                    require_once($path);
                } else {
                    $e=new Exception("Problem with path: $path");
                }
    }
    

    【讨论】:

      【解决方案3】:

      不能定义一个类,在定义实现的接口之前,任何未知的接口也会触发自动加载功能。这意味着在第 3 行中,当包含类时,它将触发自动加载函数再次,接口为$classname。现在,当从第二个__autoload()-call 返回时,它将尝试再次包含接口,但由于“已定义”而失败。

      附加:不推荐使用__autoload(),反对使用spl_autoload_register()

      【讨论】:

        猜你喜欢
        • 2011-09-20
        • 2012-12-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-07-07
        • 1970-01-01
        • 2023-04-01
        • 1970-01-01
        相关资源
        最近更新 更多