thinkphp8中事件的使用
- **事件使用主要有`事件监听`、`事件订阅`、`事件绑定`三种方式**
- 生成相关类的命令行
- 什么是自动注册
- 什么是手动注册
- 事件监听
- 监听类,listener目录下的文件
- 手动注册
- 自动注册
- 事件订阅
- 订阅类,subscribe目录下
- 手动注册
- 自动注册
- 事件绑定
- 事件类,event目录下
- 手动注册
- 自动注册
- 【重要】
- 其他
事件使用主要有事件监听、事件订阅、事件绑定三种方式
生成相关类的命令行
php think make:event 事件类名 php think make:listener 监听类名 php think make:subscribe 订单类名什么是自动注册
event.php在框架加载的时候会自动载入,在event.php文件中事先做一些处理:
- 定义
listen数组中的事件名和对应的事件处理类 - 定义
subscribe数组中的订阅类 - 定义
bind数组的事件名和对应类
什么是手动注册
就是在控制器业务代码内,写事件的监听和触发的代码,可以不用管event.php文件。
- 事件订阅 Event::subscribe(…)
- 事件监听 Event::listen(…)
- 触发事件 Event::trigger(…)
事件监听
就像html文档中,dom.addEventlistener(“click”, 事件处理函数)。然后当你点击dom的时候就会执行事件处理函数
监听类,listener目录下的文件
class EventName{ public function handle($event){ //这时候的$event应该是传过来的参数 } }手动注册
在Controller内的业务代码写 事件监听和事件触发。
// 相当于是dom.addEventlistener("click", 事件处理函数)。只是监听,你不点击我也不执行。 Event::listen("EventName", \app\listener\监听类::class); // 相当于你点击dom,会自动运行监听类里handle函数。 // 一般发问下 监听类 和 事件名 是一样的,但是含义不同,也可以不同名。例如 Event::lister("UserLogin",\app\listener\UserLogin::class) Event::trigger("UserLogin", [$params])自动注册
- 在
event.php文件定义listen数组中的事件名和对应的事件处理类
// 相当于是dom.addEventlistener("click", 事件处理函数)。只是监听,你不点击我也不执行。 'listen' => [ 'EventName' => [\app\subscribe\监听类::class] //一定是数组,一个事件可以绑定多个监听处理类 ]- Controller内的业务代码,只用触发事件就可以了。
Event::trigger("EventName", [$params])事件订阅
就你一个事件监听中心一样。只要subscribe了一个订阅类,然后就可以触发其中事件处理函数。
订阅类,subscribe目录下
use think\Event; class subName{ public function onEventName1($params){} public function onEventName2($params){} public function subscribe(Event $event) { $event->listen('EventName1', [$this,'onEventName1']); $event->listen('EventName2', [$this,'onEventName1']); } }手动注册
Controller内的业务代码
// 订阅并触发其中的事件函数。 Event::subscribe(\app\subscribe\订阅类::class); Event::trigger("EventName", [$params])自动注册
- 在
event.php文件定义subscribe数组中的订阅类
'subscribe' => [ \app\subscribe\订阅类::class ]- Controller内的业务代码
Event::trigger("EventName", [$params])注意:
如果订单类里同时有on[EventName1]和subscribe函数,那么事件触发只会调用subscribe函数。
代码结构
执行效果:
事件绑定
事件类,event目录下
一个普通类的实现代码
手动注册
Controller内的业务代码
Event::bind(['UserLogin' => 'app\event\事件类']); // 这里要用 字符串 来写事件类 Event::listen('UserLogin', \app\listener\监听类::class); //这里要用 监听类::class 来写监听类 Event::trigger(new 事件类()); //事件类传不传参,看事件类的构造函数自动注册
- 在
event.php文件定义bind数组中的事件名和事件类绑定关系
'bind' => [ // 'EventName' => [\app\event\事件类::class] // 这里不能用数组,会出错。 原来的写错了,用了数组表示 'EventName' => \app\event\事件类::class ] 'listen' => [ 'EventName' => [ \app\listener\监听类::class ] ],- Controller内的业务代码
Event::trigger(new 事件类());【重要】
你会发现没有传递EventName参数。相当于trigger函数传递了哪个事件类,就会反查到EventName,建立与listen数组对应的关系,然后再调用监听类里的handle($event)方法。这时候handle函数中的$event就是事件类的实例了,可以直接调用事件类里定义的方法完成操作。
其他
- 监听类里只有一个handle方法,当执行下面代码时会自动调用这个handle方法
Event::listen("EventName", \app\listener\监听类::class); Event::trigger("EventName", $params);- 如果想交给其他类的某个方法,可以用下面的方法
Event::listen("EventName", [\path\to\other类::class, "methodname"]);- 如果不想定义这么多类,监听时可以直接定义一个事件处理函数
Event::listen('Email', function($param){ echo "send email to ". $param['name']; }); Event::trigger('Email', ['name'=>'李四', 'age'=>30]);