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

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

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

    钩子:程序执行体;
      钩子组: 钩子链的分类定义;
           挂钩: 入口(MVC中action或者controller)与钩子组进行绑定。
 
 
 
实现方式
  
   
 
  
       挂钩器(继承类):
<?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

# 钩子组
[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
[Service_Page_Input]
#绑定钩子组
[.hook_group]
[..prev]
0 : check_req_customer
[..after]
0 : after_demo

  

 
 

 

推荐
 
 
 
 
 
 
 

php钩子程序设计的更多相关文章

  1. c++程序设计之编程思想

    代码块愈小,代码的功能就愈容易管理,代码的处理和移动就愈轻松. 任何一个傻瓜都能写出计算机可以理解的代码,唯有写出人类容易理解的代码,才是优秀的程序员. 绝大多数情况下,函数应该放在它所使用的数据的所 ...

  2. Java动态程序设计:反射介绍

    使用运行的类的信息使你的程序设计更加灵活 反射授予了你的代码访问装载进JVM内的Java类的内部信息的权限,并且允许你编写在程序执行期间与所选择的类的一同工作的代码,而不是在源代码中.这种机制使得反射 ...

  3. 使用PreTranslateMessage替代钩子函数处理键盘消息

    2002年左右,我所在公司在开发基于H.323的VoIP电话系统(用了以色列一家公司的库,具体名字忘记了). 去电信科技研究院测试系统,同事发现处理键盘消息总有一些莫名其妙的问题,比如延迟或异常. 我 ...

  4. Windows环境下32位汇编语言程序设计(典藏版)

    Windows环境下32位汇编语言程序设计(典藏版)(含CD光盘1张)(年,经典再现!) 罗云彬 著 ISBN 978-7-121-20759-4 2013年7月出版 定价:99.00元 756页 1 ...

  5. 利用钩子函数来捕捉键盘响应的windows应用程序

    一:引言: 你也许一直对金山词霸的屏幕抓词的实现原理感到困惑,你也许希望将你的键盘,鼠标的活动适时的记录下来,甚至你想知道木马在windows操作系统是怎样进行木马dll的加载的…..其实这些都是用到 ...

  6. 《windows核心编程系列》十八谈谈windows钩子

    windows应用程序是基于消息驱动的.各种应用程序对各种消息作出响应从而实现各种功能. windows钩子是windows消息处理机制的一个监视点,通过安装钩子能够达到监视指定窗体某种类型的消息的功 ...

  7. 【windows核心编程】系统消息与自定义钩子(Hook)使用

    一.HOOk Hook是程序设计中最为灵活多变的技巧之一,在windows下,Hook有两种含义: 1.系统提供的消息Hook机制 2.自定义的Hook编程技巧 其中,由系统提供的消息钩子机制是由一系 ...

  8. VC++开发Windows系统全局钩子

    本文的大部分内容属于对一篇网文的实践与练习,同时参考的还有一本书,在此向网文与书的作者表示敬意. 这个程序是一个windows系统键盘监控程序,随着开机自动启动,可以监控系统中各用户的键盘,并将按键记 ...

  9. Windows环境下32位汇编语言程序设计(典藏版)

    <Windows环境下32位汇编语言程序设计(典藏版) > 基本信息 作者: 罗云彬 出版社:电子工业出版社 ISBN:9787121207594 上架时间:2013-7-8 出版日期:2 ...

随机推荐

  1. WIN7远程桌面重启、关机

    在使用远程桌面访问Win7系统时会发现一个小问题,在xp远程桌面中存在的重启和关机菜单在win7远程桌面中不见了,如图: 这也给我们的使用带来了一些小小的麻烦,但实际上微软依然保留了命令行的方式来实现 ...

  2. avalonJS入门(一)

    前端神器avalonJS入门(一) posted @ 2014-10-31 17:44 vajoy 阅读(1665) 评论(32) 编辑 收藏   avalonJS是司徒正美开发和维护的前端mvvm框 ...

  3. Extjs中GridPanel的各个属性与方法

    1.Ext.grid.GridPanel 主要配置项: store:表格的数据集 columns:表格列模式的配置数组,可自动创建ColumnModel列模式 autoExpandColumn:自动充 ...

  4. 手机新闻网站,掌上移动新闻,手机报client,jQuery Mobile手机新闻网站,手机新闻网站demo,新闻阅读器开发

    我们坐在地铁,经常来查看新浪手机新闻,腾讯新闻.或者刷微信看新闻更多功能.你有没有想过如何实现这些目标.移动互联网,更活泼. 因为HTML5到,jQuery Moblie到.今天我用jqm为了给你一个 ...

  5. 一道sql面试题(查询语句)

    一道sql面试题(查询语句)   id name age 1  a        11 2  b        11 3  c        12 4  d        13 5  e        ...

  6. 收缩SQL Server日志不是那么简单

    收缩SQL Server日志不是那么简单的(翻译)   原文地址:http://rusanu.com/2012/07/27/how-to-shrink-the-sql-server-log/ 说明:本 ...

  7. r.js实践

    r.js合并实践 项目中用到require.js做生产时模块开发,但上线要合并压缩,幸好它配套有r.js.下面就其用法说明一下. 首先建一个目录,里面的结构如下: require.js可以到r.js项 ...

  8. iOS基础 - 数据存取

    一.iOS应用数据存储的常用方式 XML属性列表(plist)归档 Preference(偏好设置) NSKeyedArchiver归档 SQLite3 Core Data 二.应用沙盒 每个iOS应 ...

  9. twisted学习笔记No.3 Web Clients

    原创博文,转载请注明出处. 这一章我们学习利用twisted建立web 客户端. twisted.web.client.getPage用来异步下载一个页面,并且返回一个deferred from tw ...

  10. 测试Data ORM的性能

    闲着无聊,测试了一下公司ORM的性能,和其它的ORM相比,该有的都有了,不该有的也勉强塞了进去,总体考虑是并发与扩展性问题,譬如读写分离,消息总线服务整合,缓存内置. 测试机是I7,16G内存,这里只 ...