ThinkPHP6 事件的简单应用
一、序章
ThinkPHP6的手册中关于【事件】章节的介绍都是直接文字说明,给出创建的类文件,并没有一个好的示例来进行补充说明。对于刚接触【事件】的同学在阅读理解上增加了一点点困难,本文就在此结合示例简单叙述下。
二、事件
事件的使用分两种方式,一个是不使用事件类,另一个使用事件类。
1、不使用事件类
(1)使用 php think 创建一个监听类
php think make:listener UserListener
(2)打开 UserListener 类文件,echo 出 【UserListener 监听处理】,成功输入表示进入到了监听内部。
<?php declare (strict_types = 1); namespace app\listener; class UserListener { /** * 事件监听处理 * * @return mixed */ public function handle($event) { // 事件监听处理 echo $event.': UserListener 监听处理<br>'; } }
(3)注册监听。找到并打开【路径:根目录/app/event.php】event.php文件,添加内容如下:
<?php // 事件定义文件 return [ 'bind' => [ ], 'listen' => [ 'AppInit' => [], 'HttpRun' => [], 'HttpEnd' => [], 'LogLevel' => [], 'LogWrite' => [], //注册监听类 'User' => ['app\listener\UserListener'], ], 'subscribe' => [ ], ];
(4)触发事件。在需要触发的业务代码中调用。
<?php /** * Created by PhpStorm * Author: fengzi * Date: 2023/12/15 * Time: 17:24 */ namespace app\admin\controller; use think\facade\Event; class LoginController extends AdminBaseController { public function initialize() { parent::initialize(); // TODO: Change the autogenerated stub } public function login() { echo "登录成功<br>"; // 触发User事件 Event::trigger('User', '第一次'); // 使用助手函数触发User事件 event('User', '第二次'); } }
(5)使用效果展示。图中分别展示了在第(4)步中的三次输出,说明调用成功。User事件调用了两次,所以输出了两次。
(6)上面的示例为自动注册监听。还有一种是自己手动注册监听。前面(1)和(2)的步骤都是一样的,这里就不在重复贴代码了,到第(3)步时不需要注册。
<?php // 事件定义文件 return [ 'bind' => [ ], 'listen' => [ 'AppInit' => [], 'HttpRun' => [], 'HttpEnd' => [], 'LogLevel' => [], 'LogWrite' => [], ], 'subscribe' => [ ], ];
(7)触发事件。在需要触发的业务代码中手动注册并调用。
<?php /** * Created by PhpStorm * Author: fengzi * Date: 2023/12/15 * Time: 17:24 */ namespace app\admin\controller; use think\facade\Event; class LoginController extends AdminBaseController { public function initialize() { parent::initialize(); // TODO: Change the autogenerated stub } public function login() { echo "登录成功<br>"; // 注册User事件 Event::listen('User', 'app\listener\UserListener'); echo '注册成功,触发User事件<br>'; // 触发User事件 Event::trigger('User', '第一次'); // 使用助手函数触发User事件 event('User', '第二次'); } }
(8)使用效果展示。
(9)总结
不管是自动注册还是手动注册,都要注意绑定的事件名称要相同,不然无法监听成功。
2、使用事件类
(1)创建事件类文件
php think make:event UserEvent
(2)在【根目录/app/event】在找到UserEvent文件,修改成如下内容:
<?php declare (strict_types = 1); namespace app\event; class UserEvent { private $name; public function __construct(string $name) { $this->name = $name; } /** * @return string */ public function getName(): string { return $this->name; } }
(3)在【根目录/app/event.php】文件中添加UserEvent的事件绑定
<?php // 事件定义文件 return [ 'bind' => [ 'userEvent' => 'app\event\UserEvent', ], 'listen' => [ 'AppInit' => [], 'HttpRun' => [], 'HttpEnd' => [], 'LogLevel' => [], 'LogWrite' => [], ], 'subscribe' => [ ], ];
(4)创建事件监听类
php think make:listener UserListener
(5)在【根目录/app/event.php】文件中注册UserListener的监听类
<?php // 事件定义文件 return [ 'bind' => [ 'userEvent' => 'app\event\UserEvent', ], 'listen' => [ 'AppInit' => [], 'HttpRun' => [], 'HttpEnd' => [], 'LogLevel' => [], 'LogWrite' => [], //注册监听类 'UserEvent' => ['app\listener\UserListener'], ], 'subscribe' => [ ], ];
(6)打开 UserListener.php 文件,修改内容如下:
<?php declare (strict_types = 1); namespace app\listener; class UserListener { /** * 事件监听处理 * * @return mixed */ public function handle($event) { echo $event->getName().'<br>'; } }
(7)触发事件。在需要触发的业务代码中调用。
<?php /** * Created by PhpStorm * Author: fengzi * Date: 2023/12/15 * Time: 17:24 */ namespace app\admin\controller; use app\event\UserEvent; use think\facade\Event; class LoginController extends AdminBaseController { public function initialize() { parent::initialize(); // TODO: Change the autogenerated stub } public function login() { echo "登录成功<br>"; /** * 第一种触发User事件写法 * 参数1:监听名称 * 必须保证和event.php文件中的【listen】数组中的键名一致,否则无法调用成功。 * 本示例中event.php文件里配置的键值是【UserEvent】 * 参数2:事件 * 事件对象 */ Event::trigger('UserEvent', new UserEvent('张三')); /** * 第二种触发User事件写法 * 这种写法必须保证和event.php文件中的【bind】和【listen】的键名一致,否则无法调用成功。 */ Event::trigger(new UserEvent('李四')); } }
(8)运行结果展示。
(9)总结
个人理解:事件类好比发邮件这个动作,发邮件的一系列动作都写在了事件类中(其实可以看做一个独立的邮件类文件)。在你需要发送邮件的时候通过【Event::trigger()】触发一下,就可以发送邮件了。
三、事件订阅
1、事件订阅
这种方式相当于把事件写在了订阅类中,订阅类中的一个方法就是一个事件。
(1)使用 php think 创建一个订阅类
php think make:subscribe UserSubscribe
(2)打开 UserSubscribe 类文件,修改内容如下:
<?php declare (strict_types = 1); namespace app\subscribe; class UserSubscribe { public function onName($event) { echo $event.'<br>'; } }
(3)注册订阅。找到并打开【地址:根目录/app/event.php】event.php文件,添加内容如下:
<?php // 事件定义文件 return [ 'bind' => [ ], 'listen' => [ 'AppInit' => [], 'HttpRun' => [], 'HttpEnd' => [], 'LogLevel' => [], 'LogWrite' => [], ], 'subscribe' => [ 'app\subscribe\UserSubscribe', ], ];
(4)触发事件。在需要触发的业务代码中调用。
<?php /** * Created by PhpStorm * Author: fengzi * Date: 2023/12/15 * Time: 17:24 */ namespace app\admin\controller; use think\facade\Event; class LoginController extends AdminBaseController { public function initialize() { parent::initialize(); // TODO: Change the autogenerated stub } public function login() { echo "登录成功<br>"; /** * 手动注册订阅 * 如果手动注册订阅类,则不需要在配置文件(event.php)中注册,这步按需使用。 */ Event::subscribe('app\subscribe\UserSubscribe'); /** * 触发事件 * 参数1:事件名称,必须与[app\subscribe\UserSubscribe.php]文件中定义的方法名称相同(方法名要除去固定格式on) * 例如:事件方法名称为:onName,则参数1的标识名称就为:Name * 参数2:传递给事件处理函数的数据 */ Event::trigger('Name', '张三,33岁'); /** * 触发事件(使用助手函数) * 参数1:事件名称,必须与[app\subscribe\UserSubscribe.php]文件中定义的方法名称相同(方法名要除去固定格式on) * 例如:事件方法名称为:onName,则参数1的标识名称就为:Name * 参数2:传递给事件处理函数的数据 */ event('Name', '李四,34岁'); } }
(5)结果展示
2、自定义订阅
这种方式相当于在自定义订阅中调用事先定义好的事件类(项目根目录/app/event下的文件),然后自行绑定调用关系。
(1)使用 php think 创建一个事件类
php think make:event UserEvent
(2)打开 UserEvent 类文件,修改内容如下:
<?php declare (strict_types = 1); namespace app\event; class UserEvent { /** * @param $params * @return mixed */ public function getName($params) { // 打印name字段的数据 echo $params['name']; // 返回传入的数据 return $params; } /** * @param $params * @return mixed */ public function getAge($params) { // 打印age字段的数据 echo $params['age']; // 返回传入的数据 return $params; } }
(3)使用 php think 创建一个订阅类
php think make:subscribe UserSubscribe
(4)打开 UserSubscribe 类文件,修改内容如下:
<?php declare (strict_types = 1); namespace app\subscribe; use app\event\UserEvent; use think\Event; class UserSubscribe { /** * 自定义订阅 * @param Event $event * @return void * @Author: fengzi */ public function subscribe(Event $event) { // UserEvent::class 为第(2)步中创建的事件类,getName为事件类中的方法名称 $event->listen('name', [UserEvent::class, 'getName']); // UserEvent::class 为第(2)步中创建的事件类,getAge为事件类中的方法名称 $event->listen('age', [UserEvent::class, 'getAge']); } }
(5)注册订阅类。配置注册文件event.php,内容如下:
<?php // 事件定义文件 return [ 'bind' => [ ], 'listen' => [ 'AppInit' => [], 'HttpRun' => [], 'HttpEnd' => [], 'LogLevel' => [], 'LogWrite' => [], ], 'subscribe' => [ 'app\subscribe\UserSubscribe', ], ];
(6)触发订阅,在业务流程中触发订阅。
<?php /** * Created by PhpStorm * Author: fengzi * Date: 2023/12/15 * Time: 17:24 */ namespace app\admin\controller; use think\facade\Event; class LoginController extends AdminBaseController { public function initialize() { parent::initialize(); // TODO: Change the autogenerated stub } public function login() { echo "登录成功<br>"; /** * 触发订阅 * 参数1:订阅名称,名称必须要跟订阅类(UserSubscribe)中listen调用的监听名称一致 * 参数2:传递给订阅方法的参数 */ $name = Event::trigger('name', ['name'=>'李四', 'age'=>30]); /** * 触发订阅 * 参数1:订阅名称,名称必须要跟订阅类(UserSubscribe)中listen调用的监听名称一致 * 参数2:传递给订阅方法的参数 */ $age = event('age', ['name'=>'王五', 'age'=>45]); /** * 打印返回数据 * 订阅是可以返回数据的 */ dd($name, $age); } }
(7)运行程序,展示结果。
(8)总结
简单理解:
1、事件订阅就是把订阅类中的方法当作事件来用,一个方法就是一个事件,调用订阅类中的方法就是调用事件,把相关的业务写在订阅方法中就可以了。
2、自定义订阅时,订阅类其实只是个桥梁,起到绑定具体事件类的作用。具体的业务还是写在事件类中。
3、自定义订阅中可以绑定多个事件类,每个绑定都可以取一个监听名称,业务调用时使用Event::trigger('监听名称')来调用。
本文来自博客园,作者:疯子丶pony,转载请注明原文链接:https://www.cnblogs.com/mklblog/p/17914157.html