挂载点与钩子

概述

钩子,即行为扩展,是一种较为抽象的概念。它可被视为应用程序执行过程中的广义上,无论是大型业务逻辑,还是小型浏览器检测、多语言检测等,均可被视为一种行为。甚至您希望为网站用户的首次访问弹出一个“Hello, World!”的提示,也可视为一种行为。行为的存在使得无需修改框架和应用,即可通过外围扩展或配置来更改或添加功能。不同的行为之间还可能具有相同的位置属性,例如,某些行为作用于应用执行前,而某些行为作用于模板输出后。我们将这些行为发生作用的位置称为标签(位)(tag)。当应用程序运行至该标签时,将被拦截并执行相关行为。为便于开发和拓展,我们在DzzOffice 2.0中增加了相应的处理逻辑。

相关文件

  • core\class\dzz\Hook.php 行为拓展(以下简称钩子)的运行基础类文件。
  • core\class\dzz\dzz_app.php 系统运行基础类文件。

运行原理

core\class\dzz\Hook.php 提供了以下处理方法:

  1. 增加标签位(挂载点)处理程序,调用方法
/**
  * 动态添加行为扩展到某个标签
  * @param string    $tag 标签名称
  * @param string     $behavior 行为名称(即对于钩子处理程序)
  * @param bool      $first 是否放到开头执行
  * @return void
 */
 Hook::add($tag, $behavior, $first = false)
  1. 批量增加标签位(挂载点)处理程序,调用方法
/**
 * 批量导入
  * @param array        $tags 插件信息
  * @param boolean     $recursive 是否递归合并
  */
Hook::import(array $tags, $recursive = true)
  1. 获取标签位(挂载点),调用方法
/**
 *
  * @param string $tag  留空获取全部
  * @return array
 */
 Hook::get($tag = '')
  1. 调用钩子程序
/**
* @param string $tag 标签名称
  * @param mixed  $params 传入参数
  * @param mixed  $extra 额外参数
  * @param bool   $once 只获取一个有效返回值
  * @return mixed
*/
  Hook::listen($tag, &$params = null, $extra = null,$once = false)

系统对钩子加载的处理:

在 core\class\dzz\dzz_app.php 中,有以下代码:

//初始化之前导入数据库钩子
    private function _init_hook(){
        $tagfile = CACHE_DIR . BS . 'tags' . EXT;
        $data = array();
        if (file_exists($tagfile)) {//文件存在则导入文件
            $data=include $tagfile;
            //if(is_array($data)) $data=array_unique($data);
        }
        if($data){
            Hook::import($data);
        }else{
            foreach(DB::fetch_all("SELECT name,addons FROM %t where `status`='1' ORDER BY priority DESC",array('hooks')) as $value) {
                $addons = $value['addons'];//同一个挂载点下多个钩子改为多条记录
                Hook::add($value['name'],$addons);
            }
            //写入缓存文件
            $data = Hook::get();
            @file_put_contents($tagfile,"

该处理将注册系统所有的钩子,默认生成 data/cache/tags.php 缓存文件,并在判断缓存文件存在时进行注册。

对应钩子数据库表前缀_hooks表存储示例如下:

说明:上图列出了2个挂载点,分别对应部门向上同步和用户向上同步的两个挂载点。这两个挂载点下分别挂载了两个钩子程序(1. 钉钉的用户同步;2. 企业微信的用户同步)。addons为钩子程序对应类库文件路径。name即为标签位(挂载点)。

调用 Hook::listen('syntoline_user', $param); 将执行该挂载点下的两个程序,即钉钉应用的用户同步和企业微信应用的用户同步。

定义(添加)

应用的钩子程序目录位于应用下的 classes 目录(即命名空间类库目录,可使用命名空间定义),例如:

dzz/dingtalk/classes/dingtalk.php。

应用的钩子程序配置在对应应用目录下的dzz_app_应用名.xml文件中配置(如dzz/dingtalk/dzz_app_dingtalk.xml),格式如下:

xml书写规范:

1.首先添加 item 对应的 hooks 模块,如上所示,id='hooks' 的 item 即为;

2.每条钩子对应一个 item,id 对应标签位(挂载点);

3.priority 对应优先级(可忽略),若有与系统默认钩子同名或同一钩子需执行多个处理程序,可定义优先级以保证执行顺序,优先级以数值大小来区分,数值越大优先级越高;

4.description 对应描述(可忽略);

5.cdata 对应钩子程序路径,如需定义钩子执行作用域,可在路径添加 “|作用域(命名空间方式指定,中间分割符用/)”,如上定义标签位 test,在 test 应用下运行时(即用 Hook::listen('test') 调用),将先执行 dzz\test\classes\test 对应处理程序,后执行 dzz\test\classes\testa 对应处理程序。若非 test 应用下,将只执行 dzz\test\classes\test。

钩子类文件:

钩子类文件以“.php”为后缀,要求类名和文件名一致,类名称首字母大写。钩子方法定义时,建议与标签位名称一致。系统执行时,将自动在对应类文件中寻找该标签位名称方法。如果没有,则默认执行 run 方法(即钩子方法需与标签位名称一致或用 run 来命名)。

系统默认钩子,均使用命名空间定义,根据需要可不用亦可。

在钩子方法中,一旦执行 return false;,则该标签位(挂载点)下无论是否还有其它钩子程序,都将不再执行。

应用导入或安装时将根据应用文件 xml 中的 item 里的 hooks 模块配置。安装后更新系统缓存以验证钩子程序是否正确调用。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小胡2024

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值