thinkphp核心源码注释|Hook.class.php

<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006~2013 http://topthink.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------
namespace Think;
/**
 * ThinkPHP系统钩子实现
 * 这里的 这些都是 钩子机构
 * 利用行为扩展实现将动作绑定到类,将不同的动作封装到行为类里,交给不同的人同时开发。
 */
class Hook {

    static private  $tags       =   array(); // 仓库在此 哈哈

    /**
     * 动态添加插件到某个标签
     * @param string $tag 标签名称
     * @param mixed $name 插件名称
     * @return void
     * 标签添加
     */
    static public function add($tag,$name) { // tag 标签的开启
        if(!isset(self::$tags[$tag])){// 初始化 标签  挂载点
            self::$tags[$tag]   =   array();
        }
        if(is_array($name)){ // 如果是 数值了 ,就进行了 $name 里面的 产品
            self::$tags[$tag]   =   array_merge(self::$tags[$tag],$name);
        }else{
            self::$tags[$tag][] =   $name; //
        }
    }
    // 插件 跟标签,如果是数组,可以用数组直接多批量插入,如果是  单个的 话,那我们就用那里
    // 这个的功能 就是相当于 挂载了,
    // 总结的话,其实,并没什么特殊的了,哈哈,就是 仓库的数组赋值而已了
    // 这个是单独导入

    /**
     * 批量导入插件
     * @param array $data 插件信息
     * @param boolean $recursive 是否递归合并
     * @return void
     * 批量插入
     */
    static public function import($data,$recursive=true) {
        if(!$recursive){ // 覆盖导入
            self::$tags   =   array_merge(self::$tags,$data);// 进行覆盖导入,这个家伙的破坏力好大啊
        }else{ // 合并导入
            foreach ($data as $tag=>$val){ // 对数据继续拆分,处理
                if(!isset(self::$tags[$tag]))
                    self::$tags[$tag]   =   array();         // 初始化 仓库了
                if(!empty($val['_overlay'])){
                    // 可以针对某个标签指定覆盖模式
                    unset($val['_overlay']);
                    self::$tags[$tag]   =   $val; // 进行覆盖 赋值
                }else{
                    // 合并模式
                    self::$tags[$tag]   =   array_merge(self::$tags[$tag],$val);
                }// 合并模式
            }            
        }
    }// 其实就是个 总的 覆盖了 那里的
    // 上面那两个 也是一个 挂载了

    /**
     * 获取插件信息
     * @param string $tag 插件位置 留空获取全部
     * @return array
     */
    static public function get($tag='') {
        if(empty($tag)){
            // 获取全部的插件信息
            return self::$tags;
        }else{
            return self::$tags[$tag];
        }
    }
    // 通用的 那个 里面的 返回全部,跟返回必须的那个

    /**
     * 监听标签的插件
     * @param string $tag 标签名称
     * @param mixed $params 传入参数
     * @return void
     * 标签了,哈哈
     */
    static public function listen($tag, &$params=NULL) {
        if(isset(self::$tags[$tag])) { // 如果设置了 这个,否则的话,就没什么了
            if(APP_DEBUG) { // 开启记录监听
                G($tag.'Start');
                trace('[ '.$tag.' ] --START--','','INFO');
            }
            foreach (self::$tags[$tag] as $name) { // 获取了 这样的 $tag 标签里面的 产品
                APP_DEBUG && G($name.'_start');
                $result =   self::exec($name, $tag,$params); // 这里是个执行过程了
                // 这里其实已经是插件、标签、参数
                if(APP_DEBUG){
                    G($name.'_end');
                    trace('Run '.$name.' [ RunTime:'.G($name.'_start',$name.'_end',6).'s ]','','INFO');
                }
                if(false === $result) {
                    // 如果返回false 则中断插件执行
                    return ;
                }
            }
            if(APP_DEBUG) { // 记录行为的执行日志
                // 结束 监听
                trace('[ '.$tag.' ] --END-- [ RunTime:'.G($tag.'Start',$tag.'End',6).'s ]','','INFO');
            }
        }
        return;
    }

    /**
     * 执行某个插件
     * @param string $name 插件名称
     * @param string $tag 方法名(标签名)     
     * @param Mixed $params 传入的参数
     * @return void
     */
    static public function exec($name, $tag,&$params=NULL) {
        if('Behavior' == substr($name,-8) ){
            // 行为扩展必须用run入口方法
            $tag    =   'run'; // 这个是特殊说的,如果是行为的话,就必须 run 开始
        }
        $addon   = new $name(); // 否则就是 实例化
        return $addon->$tag($params); // tag 一般情况就是 方法名啊,哈哈
    }
}
// 总结:
// 第一步: 单独、全部 挂载
// 第二步: 可以获取 挂载 东西
// 第三步: 监听,说白了,就是整体执行
// 第三步: 小,就是里面的  具体的一个执行,流程,其实是可以融合在里面的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值