php中关于hook钩子函数底层理解
作者:梅坞茶坊 发布时间:2023-06-12 06:49:55
假设你有一套登录注册业务。一开始很简单,老板说只需要常规的注册登录就行。
但是到了后面,接口被刷,老板然你在注册登录前加个验证码
然后没过多久,老板又说,当用户注册时,我们给用户的邮箱或者手机发一条欢迎短信或者邮件吧
还没过上多久,老板说,当新注册时,我们给手机注册的发送200金币,给邮箱注册的发送100金币,作为注册奖励。
接着没过多久,老板说,如果一个用户超过1个月没登录的话,再次登录时,你给就给他账户发送100金币作为回归奖励,
结果过了不久,老板又说,注册时判断一下他是手机号注册还是邮箱注册,如果是邮箱就跳转 A 页面,如果是手机号就跳转 B 页面
过了一段时间,老板又说,我觉得第二个 idea 不好,我们给他去掉吧。
。。。。
等等,在业务中,我们对一个需求,会遇到各种变更,如果我们不使用 Hook ,就需要去频繁的改动主业务代码,而且还很容易出错,如果像这个情况,我们在一开始在代码中埋下以下 Hook:
「收到注册表单」
「收到登录表单」
「注册失败」
「登录失败」
那么我们只需要去处理这些 Hook 就行,丝毫不用去改动原本的代码,而且,如果我们有一天不需要某个功能,直接删除那个功能的模块代码就行。整个流程,我们的核心功能代码都没有发生过变动,如果其中一个无法使用,那我们停用掉那一个就好。
ThinkPHP的核心就是 Hook。Discuz 插件、WordPress 插件、Emlog 插件 核心都是 Hook。
举个例子:
钩子是编程里一个常见概念,非常的重要。它使得系统变得非常容易拓展,(而不用理解其内部的实现机理,这样可以减少很多工作量)。
钩子作用
钩子函数可以截获并处理其他应用程序的消息。每当特定的消息发出,在没有到达目的窗口前,钩子程序就先捕获该消息,亦即钩子函数先得到控制权。这时钩子函数即可以加工处理(改变)该消息,也可以不作处理而继续传递该消息,还可以强制结束消息的传递。
钩子实现
钩子的完整实现应该叫事件驱动。事件驱动分为两个阶段,第一个阶段是注册事件,目的是给未来可能发生的“事件”起一个名字,简单的实现方法是用单例模式产生一个持久的对象或者注册一个全局变量,然后将事件名称,以及该事件对应的类与方法插入全局变量即可。也就是挂载一个钩子。
第二个阶段是触发事件,本质上就是在事件的全局变量中查询要触发的事件名称,然后找到注册好的类与方法,实例化并运行。这样子就可以摆脱传统方式中程序必须按顺序的规则,进一步实现解除耦合的目的。
<?php
/**
* 定义钩子
*/
class Hook
{
private $hooklist = null;
//添加
public function add($people)
{
$this->hooklist[] = new $people;
}
//触发事件
public function exec()
{
foreach ($this->hooklist as $people)
{
$people->act();
}
}
}
/** 钩子实现
*/
class man
{
public function act()
{
echo 'this is man <br>';
}
}
class WoMen
{
public function act()
{
echo 'this is women <br>';
}
}
class child
{
public function act()
{
echo 'this is a child <br>';
}
}
/**注册事件
*/
class Ball
{
public function __construct()
{
$this->hook=new Hook();
}
public function down()
{
echo 'ball is downing <br>';
//添加,去掉钩子
$this->hook->add('man');
//$this->hook->add('woMen');
$this->hook->add('child');
}
public function dothing()
{
$this->hook->exec();
}
}
$ball = new Ball();
$ball->down();
$ball->dothing();
来源:https://blog.csdn.net/qq_32421489/article/details/128655989


猜你喜欢
- 本文实例讲述了Python3模拟登录操作。分享给大家供大家参考,具体如下:模拟登录_要求:1. 用户输入账号密码进行登录2. 用户信息保存在
- 本文用 Python 实现 PS 滤镜中的 USM 锐化效果import matplotlib.pyplot as pltfrom skim
- Jupyter Notebook运行代码无反应在学习人脸识别知识的过程中需要用到Anaconda 、Jupyter Notebook.我在启
- 在MySQL中,慢查询的界定时间是由MySQL内置参数变量long_query_time来指定的,其默认值为10(单位:秒),我们可以通过s
- 本文实例讲述了javascript设计模式 – 桥接模式原理与应用。分享给大家供大家参考,具体如下:介绍:如果软件系统中某个类存在两个或多个
- 通常我们在制作上图的时候,会分别给四个div加上不同的css属性,来实现中间间隔。但我们更希望的是不需要对html标签做标识,直接能通过cs
- 一、解析网站1.1 获取音频地址在喜马拉雅网站上,随便点开一个音频,打开“开发者工具”,再点击播放按钮,可以看到出现了多个请求:经过排查,发
- 问题描述使用 Navicat 导入之前转储好的 sql 文件,报错错误原因在信息日志当中往上翻,发现没有选择数据库,所以报错的原因就是没有提
- Golang 是一种现代的编程语言,它具有高效、简洁和可扩展等特点,因此在各种领域广泛应用。在 Golang 中,读取文件是一个常见的操作。
- 本文实例讲述了Mysql数据库中数据表的优化、外键与三范式用法。分享给大家供大家参考,具体如下:数据表优化将商品信息表进行优化1.创建商品种
- 1、typeof 用来检测数据类型的运算符typeof value 返回值首先是一个字符串,其次里面包含了对应的数据类型,例如:"
- 异常处理是日常操作了,但是有时候不能只能打印我们处理的结果,还需要将我们的异常打印出来,这样更直观的显示错误下面来介绍traceback模块
- 1.安装less依赖:npm install less less-loader --save 2.修改webpack.base.config
- 本文为大家分享了Windows下配置Python PyQt4开发环境的详细步骤,供大家参考,具体内容如下1. 下载相关软件Eclipse下载
- 概述在这里所谓的数据库连接是指通过网络协议与数据库服务之间建立的TCP连接。通常,与数据库服务进行通信的网络协议无需由应用程序本身实现,原因
- 前言今天,我无聊的时候做了一个搜索文章的软件,有没有更加的方便快捷不知道,好玩就行了。基于Python tkinter 制作文章
- 1、下载安装好PyCharm 专业版后打开或者新建一个Python项目,找到View导航栏,如下图:在Tool Windows下可以找到Sc
- 安装前的准备1.python的安装和配置在Window下:在开始菜单中找到运行输入cmd或直接搜索cmd点击进入,输入python,如果出现
- 如何实现让每句话的头一个字母都大写? <%dim txtFnametxtFName = &qu
- 本文实例讲述了Python实现的弹球小游戏。分享给大家供大家参考,具体如下:弹球1. Ball 类draw负责移动Ball碰撞检测,反弹,B