定义事件
新版的事件系统使用了观察者模式,提供了解耦应用的更好方式。在你需要监听事件的位置,添加如下代码:
namespace app\controller;
class User
{
public function login() {
// 用户登录业务逻辑
// ...
// 获取用户信息
$user = $this->getUserInfo();
// 分发UserLogin事件
event('UserLogin', $user);
}
}
这里的UserLogin就是你要监听的事件名,支持传入一个参数,这里我们在分发的时候传入了登录user对象,注意getUserInfo方法这里省略了,你可以自己添加(返回模型对象即可)。就可以通过事件监听来扩展额外的用户登录后的操作和业务流程。
事件监听
你可以手动注册一个事件监听
Event::listen('UserLogin', function($user) {
dump($user);
});
事件监听操作必须在事件分发之前执行才有效。
为了便于管理,我们建议使用监听器,可以通过命令行快速生成一个事件监听类
php think make:listener UserLogin
默认会生成一个app\listener\UserLogin事件监听类,也可以指定完整类名生成。
事件监听类只需要定义一个handle方法,参数就是在事件分发时候传入的user对象,也支持使用依赖注入的方式增加其它参数。
<?php
namespace app\listener;
class UserLogin
{
public function handle($user)
{
// 事件监听处理
dump($user);
}
}
在handle方法中如果返回了false,则表示监听中止,将不再执行该事件后面的监听。
定义好监听器类后,还需要注册事件监听才能生效
Event::listen('UserLogin', 'app\listener\UserLogin');
比较简单的方法是直接在事件定义文件event.php中定义对应事件的监听。
return [
'listen' => [
'UserLogin' => ['\app\listener\UserLogin'],
// 更多事件监听
],
];
事件订阅
可以通过事件订阅机制,在一个监听器中监听多个事件,例如通过命令行生成一个事件订阅者类。
php think make:subscribe User
默认会生成app\subscribe\User类,或者你可以指定完整类名生成。
然后你可以在事件订阅类中添加不同事件的监听方法,例如。
<?php
namespace app\subscribe;
class User
{
public function onUserLogin($user)
{
// 事件响应处理
}
public function onUserLogout($user)
{
// 事件响应处理
}
}
监听事件的方法命名规范是on+事件标识(驼峰命名),然后注册该事件订阅
Event::subscribe('app\subscribe\User');
一般建议直接在事件定义文件中定义
return [
'listen' => [
'UserLogin' => ['\app\listener\UserLogin'],
// 更多事件监听
],
'subscribe' => [
'\app\subscribe\User',
// 更多事件订阅
],
];
定义事件类
如果你的的事件比较复杂,你可以给要监听的事件单独定义一个类,事件类可以通过命令行快速生成
php think make:event UserLogin
事件类代码如下:
namespace app\event;
use app\model\User;
class UserLogin
{
public $user;
public function __construct(User $user)
{
$this->user = $user;
}
}
然后用下面的方式分发事件
namespace app\controller;
use app\event\UserLogin;
class User
{
public function login() {
// 用户登录业务逻辑
// ...
// 获取用户信息
$user = $this->getUserInfo();
// 分发UserLogin事件
event(new UserLogin($user));
}
}
要注意,这个时候事件监听方法的参数变成了UserLogin事件类对象而不是user对象。
Event::listen('UserLogin', function($userLogin) {
dump($userLogin->user);
});
用监听器类的话,handle方法的参数同样也是事件对象实例。
<?php
namespace app\listener;
class UserLogin
{
public function handle($userLogin)
{
// 事件监听处理
dump($userLogin->user);
}
}
事件订阅类的方法参数也是事件对象实例
<?php
namespace app\subscribe;
class User
{
public function onUserLogin($userLogin)
{
// 事件响应处理
dump($userLogin->user);
}
}
现在你已经掌握了事件类及订阅者类的基本用法。善加利用必将成为你的解耦神器!
发表评论