+ -
当前位置:首页 → 问答吧 → 【疑问】关于第七章7.1最后一段

【疑问】关于第七章7.1最后一段

时间:2009-08-27

来源:互联网

现在,需要包含希望加载的所有插件文件。在第9章中,我们将会介绍SPL(标准PHP库),你将会学到如何使用类自动加载特性,所以不再需要手工包含插件了。结果将会是一个非常容易管理的、即插即用的插件系统。
这里不知道如何理解“不再需要手工包含插件了”,如果不包含这些插件的文件,这些类的声明不可能被反射类的get_declared_classes()找到吧,那么仅通过反射类里面的new根本不可能实现即插即用。
增加一个插件,需要把插件文件给手动包含。那么autoload实现的方法是在new的时候才去调用autoload函数的吧?而spl里面根本没有new具体的对象,如此,反而觉得反射类非常累赘。
实现即插即用的方法有很多,不用手动加载也有很多,但是spl的途径我真的不理解如何实现不会手动包含插件文件就能够实现即插即用

作者: 一贯而终   发布时间: 2009-08-27

[code]<?php
/**
*
* 插件管理
*
* 即插即用的快捷插件系统
*
*
*/

// 真的没法用
//if(!defined('plug_autoload') || plug_autoload) {
//        function __autoload($name) {
//        include(dirname(__FILE__).'/'.$name.'.php');
//        }
//}
/**
* 加载所有的插件文件
*
*/
$path = 'application/plug/';
foreach(glob($path.'{*.php}', GLOB_BRACE) as $file){
    if($file!='application/plug/plug.php')
        include WEB_ROOT.'/'.$file;
}
interface plug{
    /**
     * 模板文件加载
     */
    static public function include_view($file);
    /**
     * 数据导入
     */
    static public function importData($array);
    /**
     * 生成插件
     */
    static public function out();
}

class plugManage{
    /**
     * 插件列表
     */
    private static $plugs = array();
   
    /**
     * plugManage::findPlugins()
     *
     * 查找所有插件
     *
     * @return
     */
    public static function findPlugs() {
        foreach(get_declared_classes() as $class) {
            $reflectionClass = new ReflectionClass($class);
            if($reflectionClass->implementsInterface('plug')) {
                self::$plugs[] = $reflectionClass;
            }
        }
        return self::$plugs;
    }
   
    /**
     * plugManage::computeArrayPlugs()
     *
     * 使用插件的返回数组的方法,如果有重复的插件方法,将会合并
     *
     * @param mixed $method
     * @return void
     */
    public static function computeArrayPlugs($method) {
        $result = array();
        if(empty(self::$plugs)) {
            self::findPlugs();
        }
        foreach(self::$plugs as $plug) {
            if($plug->hasMethod($method)) {
                $reflectionMethod = $plug->getMethod($method);
                if($reflectionMethod->isStatic()) {
                    $items = $reflectionMethod->invoke(null);
                } else {
                    $plugInstance = $plug->newInstance();
                    $items = $reflectionMethod->invoke($plugInstance);
                }
                $result = array_merge($result,$items);
            }
        }
        return $result;
    }
   
    /**
     * plugManage::computeStringPlugs()
     *
     * 使用插件的返回字符串的方法,如果有重复的插件方法,将会合并
     *
     * @param mixed $method
     * @return void
     */
    public static function computeStringPlugs($method) {
        $result = array();
        if(empty(self::$plugs)) {
            self::findPlugs();
        }
        foreach(self::$plugs as $plug) {
            if($plug->hasMethod($method)) {
                $reflectionMethod = $plug->getMethod($method);
                if($reflectionMethod->isStatic()) {
                    $items = $reflectionMethod->invoke(null);
                } else {
                    $plugInstance = $plug->newInstance();
                    $items = $reflectionMethod->invoke($plugInstance);
                }
                $result .= $items;
            }
        }
        return $result;
    }

}[/code]

作者: 一贯而终   发布时间: 2009-08-28

楼主看来是没有理解类的自动加载特性,__autoload()函数起的就是自动加载类库的作用,当然这个需要你进行一些设置,但是一旦你设置完成,自然就不需要重复的不断的手动加载类库,搞的到处都是require和include

作者: qxhy123   发布时间: 2009-08-29

楼主看来是没有理解类的自动加载特性,__autoload()函数起的就是自动加载类库的作用,当然这个需要你进行一些设置,但是一旦你设置完成,自然就不需要重复的不断的手动加载类库,搞的到处都是require和include
qxhy123 发表于 2009-8-29 12:47
怎么设置?好像autoload只能当$myclass = new class的时候通过他来自动获取class吧!但是spl里面的反射类可把这一步骤给反过来了。

不过我今天看到第11章的时候:创建一个插件目录的时候才知道原来spl实现即插即用并不是autoload实现的,所以之前的说法就应该有误。

[code]$dir = '/path/to/plugins';
$dirit = new DirectoryIterator($dir);

foreach($dirit as $file) {
  if(!$file->isDir()) { //Ignore directories, e.g., ./ and ../
require_once ($file);
  }
}[/code]

第十一章给出了这么一个东西,发现和我上面那短代码中的glob的功能一样,都是获得插件目录下的所有文件的include,如此,就更加表明,autoload和前面的所说的结合spl的即插即用的插件系统毫无关系。如此,在这里产生了3种方法实现即插即用:

1,autoload + 直接new一个实例
2,spl反射类 + glob
3,spl反射类 + 插件目录
而autoload和插件目录的功能差不多。

当然我们也可以这么理解,autoload并不是加载插件里面的某一个插件,而是加载插件管理类,凌驾在spl反射类之上,这样也能结合。如果是这样的一个庞大的插件系统,那么可能是我理解错误了。

作者: 一贯而终   发布时间: 2009-08-29