thinkphp(php)插件钩子(hooks)分析的简单实现机制
发布:smiling 来源: PHP粉丝网 添加日期:2023-07-02 09:28:07 浏览: 评论:0
现在主流的cms或者blog等系统中,都内置的有插件系统,但是层层深入、剖析实现的方式,其实都是最简单的钩子的复杂化的实现。
钩子是插件执行的触发器;插件就像挂在钩子上的东西;插件只有实现相应钩子方法,并安装启用成功后才能执行。
开发者也可以用hook('test')方法在控制器只加入钩子,让你的应用具有更好的扩展性;同时也可以模板里加入钩子{:hook('footer')};钩子也支持传入参数hook('footer',array('test'=>1));
向系统暴露你的钩子,就是把你的钩子在相应的文件里列出来,系统会来检测。
{:hooks('documentDetailAfter')}
这个的意思就是:相当于在这边 打一个点 ,我们可以将插件挂载到那
官方的说法是:文档末尾显示显示的 钩子
意思就是说,在文档末尾的时候,会自动调用挂载在那个 钩子 上的插件
举例说明
php中所谓的钩子,其实就是一种事件驱动,主要分为‘注册事件’、‘触发事件’两步。所谓‘注册事件’,即目的是给未来可能发生的'事情'起一个名字,名字,可以用单例模式或者注册 为一个全局的变量,用的时候直接在对应的方法或者类再或者函数中插入这个变量即可;‘触发事件’,本质上就是在事件的全局变量中查询要触发的时间名称,然后找到注册号的类与方法,实例化运行。
举个例子来说明一下。
项目经理给我们了如下的需求:
第一天:开发注册的功能。
程序员巴拉巴拉,三下五除二就完成了。
第二天:在注册前添加发送短信验证码的功能。
程序员巴拉巴拉,三峡五除二就又完成了。
第三天:注册完成之后,给用户添加相应的积分。
程序员又开始巴拉巴拉ing……
- class Register{
- public function index(){
- /**
- * 第二天发送短信功能
- */
- /**
- * 第一天注册代码
- */
- /**
- * 第三天增加积分功能
- */
- }
- }
这样一个人开发还好,多个人开发,势必会造成配合麻烦的问题,同时代码也会变得混乱。
作为优秀程序员的我们,当然不容许我们程序中代码冗余、混乱的出现,于是我们把方法写成函数独立出来,方便调用与代码简介。于是形成如下代码:
- class Register{
- public function index(){
- /**
- * 第二天发送短信功能
- */
- sendMsg($data);
- /**
- * 第一天注册代码
- */
- /**
- * 第三天增加积分功能
- */
- sendIntegral($data);
- }
- }
- /**
- * 发送短信
- * @param {[type]} $data [description]
- * @return {[type]} [description]
- */
- function sendMsg($data){
- /*
- balabala
- */
- }
- /**
- * 赠送积分
- * @param {[type]} $data [description]
- * @return {[type]} [description]
- */
- function sendIntegral($data){
- /*
- balabala
- */
- }
但是我们想要把程序开元出去让更多的人参与,这种直接修改源码码的方式始终不是太好,这个时候,我们就可以使用钩子的方式,在注册成功前后注册两个钩子,我们只需要把钩子告诉开发人员就行了,这样他们不用改变源码码就可以轻易的进行拓展。
- class Register{
- public function index(){
- //注册前钩子
- Hook::run('registerBefore');
- /**
- * 注册代码
- */
- //注册后钩子
- Hook::run('registerAfter');
- }
- }
钩子的简单实现代码
目录结构:../hook/Hook.php
钩子核心类Hook.php:
- <?php
- namespace hook;
- class Hook{
- static protected $hook = [];
- /**
- * 插件注册
- * @param [type] $name [description]
- * @param [type] $addons [description]
- */
- static public function add($name,$addons){
- self::$hook[$name] = $addons;
- }
- /**
- * 插件执行
- * @param [type] $name [description]
- * @return [type] [description]
- */
- static public function run($name){
- if(isset(self::$hook[$name])){
- $method = (new self::$hook[$name]());
- call_user_func([$method,$name]);
- }
- }
- }
简单的插件demo:
- <?php
- namespace addons\demo;
- class Demo{
- public function registerBefore(){
- echo 'registerBefore'.'</br>';
- }
- public function registerAfter(){
- echo 'registerAfter'.'</br>';
- }
- }
插件实现的地方,即上文的注册的文件:
- <?php
- namespace index\controller;
- use hook\Hook;
- class Index{
- public function index(){
- Hook::run('registerBefore');
- echo '注册完成'.'</br>';
- Hook::run('registerAfter');
- }
- }
入口文件index.php
- <?php
- use index\controller\Index;
- spl_autoload_register('autoload');
- function autoload($name){
- require_once('/'.str_replace('\\','/',$name).'.php');
- }
- //插件注册
- hook\Hook::add('registerBefore','\\addons\\demo\\Demo');
- hook\Hook::add('registerAfter','\\addons\\demo\\Demo');
- //调用
- $index = new Index();
- $index->index();
运行接口如下:
registerBefore
注册完成
registerAfter
如果要添加新的功能,程序员只要修改demo的插件就可,如果要拓展新的功能,只需要拓展registerBefore和registerAfter即可。
总结:
可以说,钩子就是挂载点。
挂载点:在系统中提供给你一个挂载点,我们可以进行插件开发,开发完成后,我们将其挂载到 挂载点上,会自动调用执行。
Tags: thinkphp插件钩子 hooks
- 上一篇:ThinkPHP5集成JS-SDK实现微信自定义分享功能
- 下一篇:最后一页
推荐文章
热门文章
最新评论文章
- 写给考虑创业的年轻程序员(10)
- PHP新手上路(一)(7)
- 惹恼程序员的十件事(5)
- PHP邮件发送例子,已测试成功(5)
- 致初学者:PHP比ASP优秀的七个理由(4)
- PHP会被淘汰吗?(4)
- PHP新手上路(四)(4)
- 如何去学习PHP?(2)
- 简单入门级php分页代码(2)
- php中邮箱email 电话等格式的验证(2)