onethink里面有一个插件的功能,也就是所谓的钩子,钩子就是挂在墙壁上的一个东西,插件就是相关的好比如衣服等等,只要想要,可以把衣服等等都往钩子上挂。

下面先说这个钩子的流程,onethink是用thinkphp框架开发的,刚开始都是先加载里面的一些核心代码,里面包括onethinkphpThinkPHPLibraryThinkApp.class.php这些核心的代码。那这里面先监听一些系统设定的在哪个过程出现的钩子

        // 应用初始化标签
        Hook::listen('app_init');
        App::init();
        // 应用开始标签
        Hook::listen('app_begin');
        // Session初始化
        if(!IS_CLI){
            session(C('SESSION_OPTIONS'));
        }
        // 记录应用初始化时间
        G('initTime');
        App::exec();
        // 应用结束标签
        Hook::listen('app_end');

 

当然过程不止这些,还有相同目录下面的View.class.php这个系统显示的文件,里面也有相关的钩子

    public function display($templateFile='',$charset='',$contentType='',$content='',$prefix='') {
        G('viewStartTime');
        // 视图开始标签
        Hook::listen('view_begin',$templateFile);
        // 解析并获取模板内容
        $content = $this->fetch($templateFile,$content,$prefix);
        // 输出模板内容
        $this->render($content,$charset,$contentType);
        // 视图结束标签
        Hook::listen('view_end');
    }

 

   public function fetch($templateFile='',$content='',$prefix='') {
        if(empty($content)) {
            $templateFile   =   $this->parseTemplate($templateFile);
            // 模板文件不存在直接返回
            if(!is_file($templateFile)) E(L('_TEMPLATE_NOT_EXIST_').':'.$templateFile);
        }
        // 页面缓存
        ob_start();
        ob_implicit_flush(0);
        if('php' == strtolower(C('TMPL_ENGINE_TYPE'))) { // 使用PHP原生模板
            $_content   =   $content;
            // 模板阵列变量分解成为独立变量
            extract($this->tVar, EXTR_OVERWRITE);
            // 直接载入PHP模板
            empty($_content)?include $templateFile:eval('?>'.$_content);
        }else{
            // 视图解析标签
            $params = array('var'=>$this->tVar,'file'=>$templateFile,'content'=>$content,'prefix'=>$prefix);
            Hook::listen('view_parse',$params);
        }
        // 获取并清空缓存
        $content = ob_get_clean();
        // 内容过滤标签
        Hook::listen('view_filter',$content);
        // 输出模板文件
        return $content;
    }

 

里面的hook都是相关的监听的钩子。

然后要在哪个地方进行挂上在哪个钩子上面的可以在相关的conf配置文件里面新建一个tags.php,然后在里面设置相关的哪些位置加载哪些行为

<?php
return array(
	'app_init'=>array('CommonBehaviorInitHookBehavior'),
	'view_filter'=>array('BehaviorTokenBuildBehavior')//表单token
);

这个是自己配置的一些例子。

然后系统就会初始化相关的文件,比如表单token的在onethinkphpThinkPHPLibraryBehaviorTokenBuildBehavior.class.php这个文件,今天我们讲钩子和插件,我们就看看

onethinkphpApplicationCommonBehaviorInitHookBehavior.class.php这个文件

直接贴上里面的全部代码

namespace CommonBehavior;
use ThinkBehavior;
use ThinkHook;
defined('THINK_PATH') or exit();

// 初始化钩子信息
class InitHookBehavior extends Behavior {

    // 行为扩展的执行入口必须是run
    public function run(&$content){
        if(defined('BIND_MODULE') && BIND_MODULE === 'Install') return;

        $data = S('hooks');
        if(!$data){
            $hooks = M('Hooks')->getField('name,addons');
            foreach ($hooks as $key => $value) {
                if($value){
                    $map['status']  =   1;
                    $names          =   explode(',',$value);
                    $map['name']    =   array('IN',$names);
                    $data = M('Addons')->where($map)->getField('id,name');
                    if($data){
                        $addons = array_intersect($names, $data);
                        Hook::add($key,array_map('get_addon_class',$addons));
                    }
                }
            }
            S('hooks',Hook::get());
        }else{
            Hook::import($data,false);
        }
    }
}

 

该类是继承Behavior这个基类。上面这些代码就是初始化钩子所需要挂的相关的插件,从数据库里面查询出来以及一些初始化。

然后看看模版里面是怎么触发的。模版里面

       <!-- 插件块 -->
       <div class="container-span">{:hook('AdminIndex')}</div>

 

该代码就是通过onethinkphpApplicationCommonBehaviorInitHookBehavior.class.php文件查找app_init的时候加载的AdminIndex的钩子上面挂了哪些插件,然后把相关的插件输出出来。

以上这些就是自己对onethink的插件的相关理解!

以后要再好好学习,学习一下discuz相关的插件机制!