首页 > php框架 > ThinkPHP > 正文

thinkphp插件钩子的实现机制是什么

WBOY
发布: 2023-05-27 09:07:43
转载
1918人浏览过

    现在主流的cms或者blog等系统中,都内置的有插件系统,但是层层深入、剖析实现的方式,其实都是最简单的钩子的复杂化的实现。

    前言

    插件的执行通过钩子来触发;可以把插件看作挂在钩子上的东西;插件只有在成功实现相应钩子方法并被正确安装启用后才能执行。

    开发者也可以用hook('test')方法在控制器只加入钩子,让你的应用具有更好的扩展性;同时也可以模板里加入钩子{:hook('footer')};钩子也支持传入参数hook('footer',array('test'=>1));

    向系统暴露你的钩子,就是把你的钩子在相应的文件里列出来,系统会来检测。

    {:hooks('documentDetailAfter')}
    登录后复制

    这个的意思就是:相当于在这边 打一个点 ,我们可以将插件挂载到那
    官方的说法是:文档末尾显示显示的 钩子
    意思就是说,在文档末尾的时候,会自动调用挂载在那个 钩子 上的插件

    立即学习PHP免费学习笔记(深入)”;

    举例说明

    php中所谓的钩子,其实就是一种事件驱动,主要分为‘注册事件’、‘触发事件’两步。所谓‘注册事件’,即目的是给未来可能发生的'事情'起一个名字,名字,可以用单例模式或者注册 为一个全局的变量,用的时候直接在对应的方法或者类再或者函数中插入这个变量即可;‘触发事件’,本质上就是在事件的全局变量中查询要触发的时间名称,然后找到注册号的类与方法,实例化运行。
    举个例子来说明一下。
    项目经理给我们了如下的需求:
    第一天:开发注册的功能。
    程序员巴拉巴拉,三下五除二就完成了。
    第二天:在注册前添加发送短信验证码的功能。
    程序员巴拉巴拉,三峡五除二就又完成了。
    第三天:注册完成之后,给用户添加相应的积分。
    程序员又开始巴拉巴拉ing……

    小鸽子助手
    小鸽子助手

    一款集成于WPS/Word的智能写作插件

    小鸽子助手 26
    查看详情 小鸽子助手
        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 addonsdemo;
        class Demo{
            public function registerBefore(){
                echo 'registerBefore'.'</br>';
            }
            public function registerAfter(){
                echo 'registerAfter'.'</br>';
            }    
        }
    登录后复制

    插件实现的地方,即上文的注册的文件:

        <?php
        namespace indexcontroller;
        use hookHook;
        class Index{
            public function index(){
                Hook::run('registerBefore');
                echo '注册完成'.'</br>';
                Hook::run('registerAfter');
                
            }
        }
    登录后复制

    入口文件index.php

        <?php
        use indexcontrollerIndex;
        spl_autoload_register('autoload');
        function autoload($name){
            require_once('/'.str_replace('\','/',$name).'.php');
        }
        //插件注册
        hookHook::add('registerBefore','\addons\demo\Demo');
        hookHook::add('registerAfter','\addons\demo\Demo');
        //调用
        $index = new Index();
        $index->index();
    登录后复制

    运行接口如下:

        registerBefore    注册完成    registerAfter

    如果要添加新的功能,程序员只要修改demo的插件就可,如果要拓展新的功能,只需要拓展registerBefore和registerAfter即可。 

    以上就是thinkphp插件钩子的实现机制是什么的详细内容,更多请关注php中文网其它相关文章!

    PHP速学教程(入门到精通)
    PHP速学教程(入门到精通)

    PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

    下载
    来源:亿速云网
    本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
    最新问题
    开源免费商场系统广告
    热门教程
    更多>
    最新下载
    更多>
    网站特效
    网站源码
    网站素材
    前端模板
    关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新 English
    php中文网:公益在线php培训,帮助PHP学习者快速成长!
    关注服务号 技术交流群
    PHP中文网订阅号
    每天精选资源文章推送
    PHP中文网APP
    随时随地碎片化学习

    Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号