thinkphp(php)插件钩子(hooks)分析的简单实现机制

 更新时间:2023年3月14日 16:27  点击:299

现在主流的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即可。 

总结

可以说,钩子就是挂载点。

挂载点:在系统中提供给你一个挂载点,我们可以进行插件开发,开发完成后,我们将其挂载到 挂载点上,会自动调用执行。

到此这篇关于thinkphp(php)插件钩子(hooks)分析的简单实现机制的文章就介绍到这了,更多相关php插件钩子(hooks)内容请搜索猪先飞以前的文章或继续浏览下面的相关文章希望大家以后多多支持猪先飞!

[!--infotagslink--]

相关文章

  • 源码分析系列之json_encode()如何转化一个对象

    这篇文章主要介绍了源码分析系列之json_encode()如何转化一个对象,对json_encode()感兴趣的同学,可以参考下...2021-04-22
  • php中去除文字内容中所有html代码

    PHP去除html、css样式、js格式的方法很多,但发现,它们基本都有一个弊端:空格往往清除不了 经过不断的研究,最终找到了一个理想的去除html包括空格css样式、js 的PHP函数。...2013-08-02
  • jQuery Mobile开发中日期插件Mobiscroll使用说明

    这篇文章主要介绍了jQuery Mobile开发中日期插件Mobiscroll使用说明,需要的朋友可以参考下...2016-03-03
  • index.php怎么打开?如何打开index.php?

    index.php怎么打开?初学者可能不知道如何打开index.php,不会的同学可以参考一下本篇教程 打开编辑:右键->打开方式->经文本方式打开打开运行:首先你要有个支持运行PH...2017-07-06
  • Jquery日历插件制作简单日历

    在页面开发中,经常遇到需要用户输入日期的操作。通常的做法是,提供一个文本框(text),让用户输入,然后,编写代码验证输入的数据,检测其是否是日期类型。这样比较麻烦,同时,用户输入日期的操作也不是很方便,影响用户体验。如果使...2015-10-30
  • vue-cli 3如何使用vue-bootstrap-datetimepicker日期插件

    这篇文章主要介绍了vue-cli 3如何使用vue-bootstrap-datetimepicker日期插件,帮助大家更好的理解和学习使用vue框架,感兴趣的朋友可以了解下...2021-02-20
  • 使用JQuery实现的分页插件分享

    一个简单的jQuery分页插件,兼容AMD规范和requireJS./** * jQuery分页插件 * */;(function (factory) { if (typeof define === "function" && define.amd) { // AMD模式 define([ "jquery" ], factory); } els...2015-11-08
  • PHP中func_get_args(),func_get_arg(),func_num_args()的区别

    复制代码 代码如下:<?php function jb51(){ print_r(func_get_args()); echo "<br>"; echo func_get_arg(1); echo "<br>"; echo func_num_args(); } jb51("www","j...2013-10-04
  • Bootstrap教程JS插件滚动监听学习笔记分享

    这篇文章主要为大家分享了Bootstrap教程JS插件滚动监听学习笔记,内容很详细,感兴趣的小伙伴们可以参考一下...2016-05-20
  • PHP编程 SSO详细介绍及简单实例

    这篇文章主要介绍了PHP编程 SSO详细介绍及简单实例的相关资料,这里介绍了三种模式跨子域单点登陆、完全跨单点域登陆、站群共享身份认证,需要的朋友可以参考下...2017-01-25
  • Jquery插件实现点击获取验证码后60秒内禁止重新获取

    通过jquery.cookie.js插件可以快速实现“点击获取验证码后60秒内禁止重新获取(防刷新)”的功能效果图:先到官网(http://plugins.jquery.com/cookie/)下载cookie插件,放到相应文件夹,代码如下:复制代码 代码如下: <!DOCTYPE ht...2015-03-15
  • jquery自定义插件开发之window的实现过程

    这篇文章主要介绍了jquery自定义插件开发之window的实现过程的相关资料,需要的朋友可以参考下...2016-05-09
  • PHP实现创建以太坊钱包转账等功能

    这篇文章主要介绍了PHP实现创建以太坊钱包转账等功能,对以太坊感兴趣的同学,可以参考下...2021-04-20
  • 50 个 jQuery 插件可将你的网站带到另外一个高度

    Query架构的开发人员能够创建一个插件代码来扩展其功能,从而能够产生一些最好的插件,让你的网站或任何给定的项目达到一个全新的水平。 ...2016-04-27
  • 解决vue中使用swiper 插件出错的问题

    这篇文章主要介绍了vue中使用swiper 插件出错问题及解决办法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-08-22
  • jquery表单插件form使用方法详解

    这篇文章主要为大家详细介绍了jquery插表单件form使用方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2017-01-23
  • php微信公众账号开发之五个坑(二)

    这篇文章主要为大家详细介绍了php微信公众账号开发之五个坑,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2016-10-02
  • 解决jquery插件:TypeError:$.browser is undefined报错的方法

    首先先说一说$.browser browser就是用来获取浏览器基本信息的。 jQuery 从 1.9 版开始,移除了 $.browser 和 $.browser.version , 取而代之的是 $.support 。 在更新的 2.0 版本中,将不再支持 IE 6/7/8。 以后,如果用户需...2015-11-24
  • PHP如何通过date() 函数格式化显示时间

    这篇文章主要介绍了PHP如何通过date() 函数格式化显示时间,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-11-13
  • vue中jsonp插件的使用方法示例

    这篇文章主要给大家介绍了关于vue中jsonp插件的使用方法示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-09-10