dmz社区

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 6710|回复: 89

[功能实现] php钩子程序设计以及原理

  [复制链接]
  • TA的每日心情

    2024-11-19 20:46
  • 签到天数: 244 天

    [LV.8]以坛为家I

    4434

    主题

    1459

    帖子

    1万

    积分

    会|员

    Rank: 9Rank: 9Rank: 9

    积分
    10734
    发表于 2019-1-3 17:17:54 | 显示全部楼层 |阅读模式

    本站资源全部免费,回复即可查看下载地址!

    您需要 登录 才可以下载或查看,没有帐号?立即注册

    x
       作为程序员,设计出优雅而完美的系统,永远是让我们非常兴奋的事情。高手不在于你会多少语言,而在于你有多高的思想。   在设计中,怎么体现自身价值,那就是要比别人多想几步。   讲钩子程序,起源是对用户提交的参数校验(永远不要相信用户),一开始为了赶工期,按照比较传统的方式,每个接口里重复性的对参数进行过滤。后面随着业务的发展(功能迭代),系统的维护成本越来越高,遂想一个更高级的方式进行处理。借鉴同事之前的代码,使用钩子方式进行重构。   之前写过javascript 钩子机制, 偏后钩,可以互相借鉴下。

    脉路    

    概念    
    把一段程序块(执行体)通过某种方式挂入系统中,从而获得对系统的控制权。        
    注意下图挂钩位置:
      


    应用    

      小的方面: 进行基础的入参校验或消息过滤。
      大的方面:组件化,可在系统中进行插拔管理。
      
      优点:
        1、降低系统的耦合度;
        2、降低开发、测试人力成本,用少量的代码实现高可用功能;
        3、提高模块间的可用性;
        4、通过配置(配置文件or数据库)的方式升级接口。
      缺点:
        学习成本过高;
        系统复杂度提升;



    实现思想        
    配置文件的方式进行钩子定义、钩子链管理(使用“组”的概念)、挂钩。   


        钩子:程序执行体;     
    钩子组: 钩子链的分类定义;           
    挂钩: 入口(MVC中action或者controller)与钩子组进行绑定。  
    实现方式               
    挂钩器(继承类):
    [PHP] 纯文本查看 复制代码
    <?php
    /**
     * @name Service_Page_Test
     * @desc page层对接第三方抽象类
     * @author 
     */
    abstract class Service_Page_Test
    {
        public $hookGroupPrev = null; // 前钩子组
        public $hookGroupAfter = null; // 后钩子组
        public $hookReturn = array(); //钩子返回值
        public $reqData = null; // page模块分析的数据
     
        /**
         * 获取需要验证的参数配置
         * @return array
         */
        public function _getCheckParams()
        {
            return array();
        }
     
     
     
        /**
         * 入口方法
         * @param array $arrInput
         * @return array
         */
        public function execute($arrInput)
        {
            $res = array(
                'errno' => Test_Errno::ERRNO_SUCCESS,
                'errmsg' => Test_Errno::$ERRMSG[Test_Errno::ERRNO_SUCCESS],
            );
            try {
                $this->_init($arrInput);
                $this->_beforeExecute();
                $res = $this->doExecute($arrInput);
                $this->_afterExecute();
            } catch (Test_Exception $e) {
                $res = array(
                    'errno' => $e->getCode(),
                    'errmsg' => $e->getMessage(),
                );
            } catch (Exception $e) {
                $res = array(
                    'errno' => $e->getCode(),
                    'errmsg' => $e->getMessage(),
                );
     
            }
            return $res;
        }
     
     
     
        /**
         * auto exec
         * @param array $arrInput
         * @throws Exception
         * @return array
         */
        protected function doExecute($arrInput){
        }
     
     
        /**
         * 获取权限信息
         * @param array $arrInput
         * @return array
         */
        public function _init($arrInput)
        {
            $pageModulesConf = Conf::getConf('page/' . get_class($this));
            $this->reqData = $arrInput;
            $this->hookGroupPrev[] = $pageModulesConf['hook_group']['prev'];
            $this->hookGroupAfter[] = $pageModulesConf['hook_group']['after'];
        }
     
     
        /**
         * 执行filter
         * @param string
         */
        public function _beforeExecute()
        {
            if (!empty($this->hookGroupPrev) && is_array($this->hookGroupPrev)) {
                foreach ($this->hookGroupPrev as $hookGroups) {
                    foreach ($hookGroups as $hookGroup) {
                        $this->_executeHook($hookGroup, $this->reqData);
                    }
                }
            }
        }
     
     
        /**
         * @param array $arrInput
         * @return array
         */
        public function _afterExecute()
        {
            if (!empty($this->hookGroupAfter) && is_array($this->hookGroupAfter)) {
                foreach ($this->hookGroupAfter as $hookGroups) {
                    foreach ($hookGroups as $hookGroup) {
                        $this->_executeHook($hookGroup, $this->reqData);
                    }
                }
            }
        }
     
     
        /**
         * 执行filter
         * @param string
         */
        public function _executeHook($hookGroup, $reqData)
        {
     
            $hookGroupConf = Conf::getConf('hook/group/' . $hookGroup);
            if(!empty($hookGroupConf)){
                foreach($hookGroupConf as $hook){
                    $hookConf = Conf::getConf('hook/hook/' . $hook);
                    $class = $hookConf['class'];
                    $method = $hookConf['method'];
                    $inputParams = isset($hookConf['getInputParams']) ? $this->{$hookConf['getInputParams']}() : null;
                    if (class_exists($class)) {
                        $obj = new $class();
                        if (method_exists($obj, $method)) {
                            $this->hookReturn[$hook][] =  $obj->$method($inputParams, $reqData);
                        }
                    }
                }
            }
     
        }
     
    }


    hook.conf
    [AppleScript] 纯文本查看 复制代码
    # 钩子组
    [group]
    [.check_req_customer]
    : checkReqCustomerBaseInfo
    [.after_demo]
    : afterDemo
    
    # 钩子
    [hook]
    [.checkReqCustomerBaseInfo]
    class:  Service_Page_Hook_Customer
    method: checkBaseInfo
    getInputParams: _getCheckParams
    
    [.afterDemo]
    class:  Service_Page_Hook_Customer
    method: afterDemo
    getInputParams: _getCheckParams



    page.conf
    [AppleScript] 纯文本查看 复制代码
    [Service_Page_Input]
    #绑定钩子组
    [.hook_group]
    [..prev]
    0 : check_req_customer
    [..after]
    0 : after_demo



    推荐   

       

    回复

    使用道具 举报

    该用户从未签到

    20

    主题

    7940

    帖子

    1037

    积分

    荣誉会员

    积分
    1037

    发表于 2019-1-9 15:44:29 | 显示全部楼层
    学习了,不错,讲的太有道理了
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    20

    主题

    7658

    帖子

    937

    积分

    终身会员[A]

    Rank: 7Rank: 7Rank: 7

    积分
    937

    发表于 2019-1-10 05:59:56 | 显示全部楼层
    正需要,支持楼主大人了!
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    3

    主题

    3508

    帖子

    -6

    积分

    终身会员[A]

    Rank: 7Rank: 7Rank: 7

    积分
    -6

    发表于 2019-1-10 14:21:39 | 显示全部楼层
    路过,支持一下啦
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    28

    主题

    7920

    帖子

    1033

    积分

    终身会员[A]

    Rank: 7Rank: 7Rank: 7

    积分
    1033

    发表于 2019-1-12 01:07:43 | 显示全部楼层
    么有分,谁能送我点积分啊::>_<::
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    23

    主题

    8041

    帖子

    1038

    积分

    终身会员[A]

    Rank: 7Rank: 7Rank: 7

    积分
    1038

    发表于 2019-1-14 15:17:23 | 显示全部楼层
    没看完~~~~~~ 先顶,好同志
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    29

    主题

    7959

    帖子

    979

    积分

    终身会员[A]

    Rank: 7Rank: 7Rank: 7

    积分
    979

    发表于 2019-1-16 23:32:45 | 显示全部楼层
    有道理。。。
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    20

    主题

    7880

    帖子

    986

    积分

    终身会员[A]

    Rank: 7Rank: 7Rank: 7

    积分
    986

    发表于 2019-1-18 11:03:03 | 显示全部楼层
    我是来刷分的,嘿嘿
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    1

    主题

    3454

    帖子

    -12

    积分

    终身会员[A]

    Rank: 7Rank: 7Rank: 7

    积分
    -12

    发表于 2019-1-21 13:24:41 | 显示全部楼层
    学习了,不错,讲的太有道理了
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    54

    主题

    7806

    帖子

    998

    积分

    终身会员[A]

    Rank: 7Rank: 7Rank: 7

    积分
    998

    发表于 2019-1-22 17:20:33 | 显示全部楼层
    没看完~~~~~~ 先顶,好同志
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|Archiver|小黑屋|本站代理|dmz社区

    GMT+8, 2024-12-23 23:52 , Processed in 1.342387 second(s), 41 queries .

    Powered by Discuz! X3.4 Licensed

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表