举个例子来说明一下。
项目经理给我们了如下的需求:
第一天:开发注册的功能。
程序员巴拉巴拉,三下五除二就完成了。
第二天:在注册前添加发送短信验证码的功能。
程序员巴拉巴拉,三峡五除二就又完成了。
第三天:注册完成之后,给用户添加相应的积分。
程序员又开始巴拉巴拉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.php:
<?php
/**
* @Author: CraspHB彬
* @Date: 2018-12-20 11:39:53
* @Email: 646054215@qq.com
* @Last Modified time: 2018-12-20 17:06:58
*/
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
/**
* @Author: CraspHB彬
* @Date: 2018-12-20 11:49:57
* @Email: 646054215@qq.com
* @Last Modified time: 2018-12-20 17:05:32
*/
namespace addons\demo;
class Demo{
public function registerBefore(){
echo 'registerBefore'.'</br>';
}
public function registerAfter(){
echo 'registerAfter'.'</br>';
}
}插件实现的地方,即上文的注册的文件(此处用的为index而非register,主要是懒得改了): <?php
/**
* @Author: CraspHB彬
* @Date: 2018-12-20 11:26:44
* @Email: 646054215@qq.com
* @Last Modified time: 2018-12-20 17:05:39
*/
namespace index\controller;
use hook\Hook;
class Index{
public function index(){
Hook::run('registerBefore');
echo '注册完成'.'</br>';
Hook::run('registerAfter');
}
}入口文件index.php <?php
/**
* @Author: CraspHB彬
* @Date: 2018-12-20 11:27:46
* @Email: 646054215@qq.com
* @Last Modified time: 2018-12-20 17:03:36
*/
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即可。还是上传不了图片,擦擦擦。
更多点击博客 http://crasphter.cn/article/27 查看
最佳答案