挂载点与钩子

2024-07-05 19:54 更新

概述

钩子,即行为扩展,是一种较为抽象的概念。它可被视为应用程序执行过程中的广义上,无论是大型业务逻辑,还是小型浏览器检测、多语言检测等,均可被视为一种行为。甚至您希望为网站用户的首次访问弹出一个“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,"<?php \t\n return ".var_export($data,true).";"); } }

该处理将注册系统所有的钩子,默认生成 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 模块配置。安装后更新系统缓存以验证钩子程序是否正确调用。


以上内容是否对您有帮助:
在线笔记
App下载
App下载

扫描二维码

下载编程狮App

公众号
微信公众号

编程狮公众号