服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - PHP教程 - Thinkphp事件机制两种实现方式详解

Thinkphp事件机制两种实现方式详解

2022-11-21 16:26firstime_tzjz PHP教程

根据官方文档thinkphp6的事件机制涉及三个类:事件类(event)、监听类(listener)、订阅类(subscribe)。官方的文档以及官方的视频都没把事件机制讲清楚。下面我以单应用为例用另一种方式给大家总结一下

事件机制的实现有两种途径:通过监听、通过订阅

一、通过监听

1、创建监听类:在命令行模式下进入框架根目录执行

php think make:listener <自定义的类名>

例如:

php think make:listener UserListener

执行之后将在<框架根目录>\app\listener\下生成UserListener这个类。

2、配置监听:在<框架根目录>\app\event.php这个文件的listen数组中配置UserListener这个类,如下:

'listen'    => [
    'testEvent' => ['app\listener\UserListener']
],

3、触发监听:在你需要触发监听的地方加入如下代码

?
1
event('testEvent');

注意:这里的参数testEvent即为事件名称,可随便定义,但必须要与在event.php文件里配置的键名一致。

触发监听时你可以带上第二个参数。通过第二个参数你可以把任何数据传递到UserListener这个类中,也就是handle方法的参数(不明白啥意思的结合下面的完整代码理解)。

4、处理监听逻辑:在UserListener类的handle方法中完成业务逻辑

完整代码如下

Other:一个用来测试的类

?
1
2
3
4
5
6
7
8
9
<?php
namespace app\controller;
class Other
{
    public function hello()
    {
        echo 'hello function';
    }
}

Index:触发监听的类

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<?php
namespace app\controller;
use app\BaseController;
class Index extends BaseController
{
    public $name  = 'index';
    public function test1()
    {
        //触发监听事件,无参数
        event('testEvent');
    }
    public function test2()
    {
        //触发监听事件,传递字符串
        event('testEvent', 'hello');
    }
    public function test3()
    {
        //触发监听事件,传递自身类
        event('testEvent', $this);
    }
    public function test4()
    {
        //触发监听事件,传递其他类
        $other  = new Other();
        event('testEvent', $other);
    }
}

UserListener:事件监听类

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?php
namespace app\listener;
class UserListener
{
    /**
     * 事件监听处理
     *
     * @return mixed
     */
    public function handle($event)
    {
        //当调用Index类的test1方法时该代码有效,$event为null
        var_dump($event);
        //当调用Index类的test2方法时该代码有效,$event为字符串hello
        var_dump($event);
        //当调用Index类的test3方法时该代码有效,$event为Index类的实例
        //可以访问Index类的name变量
        echo $event->name;
        //当调用Index类的test4方法时该代码有效,$event为Other类的实例
        //可以调用Other类的hello方法
        echo $event->hello();
    }
}

二、通过订阅

1、创建订阅类

在命令行模式下进入框架根目录执行

php think make:subscribe <自定义的类名>

例如:

php think make:subscribe UserSubscribe

执行之后将在<框架根目录>\app\subscribe\下生成UserSubscribe这个类。

2、配置监听

在<框架根目录>\app\event.php这个文件的subscribe数组中配置UserSubscribe这个类,如下:

'subscribe' => ['app\subscribe\UserSubscribe'],

注意:为了测试效果,要把上面配置的UserListener从listen数组删除掉

3、触发监听

跟第一种途径一样

4、处理监听逻辑

处理监听的逻辑又有两种方法,我称之为自动绑定和手动绑定。手动绑定和自动绑定是互斥的,只能二选一。

4.1 自动绑定

在UserSubscribe类中添加ontestEvent方法,在该方法中完成业务逻辑。添加的方法名不能随意定义,规则是事件名称前面加上on。因为我们在event.php里定义的事件名称是testEvent,所以方法名就是ontestEvent(注意大小写)。监听方法定义之后就自动与事件绑定,所以我称之为自动绑定。

完整代码如下

Other和Index类的代码跟第一种途径一样

UserSubscribe:事件订阅类

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php
namespace app\subscribe;
class UserSubscribe
{
    public function ontestEvent($user)
    {
        //当调用Index类的test1方法时该代码有效,$event为null
        var_dump($user);
        //当调用Index类的test2方法时该代码有效,$event为字符串hello
        var_dump($user);
        //当调用Index类的test3方法时该代码有效,$event为Index类的实例
        //可以访问Index类的name变量
        echo $user->name;
        //当调用Index类的test4方法时该代码有效,$event为Other类的实例
        //可以调用Other类的hello方法
        echo $user->hello();
    }
}

4.2 手动绑定

首先,创建事件类,负责处理具体的业务逻辑。在命令行模式下进入框架根目录执行:

php think make:event <自定义的类名>

例如:

php think make:event UserEvent

执行之后将在<框架根目录>\app\event\下生成UserEvent这个类。

再在该类中定义一个handle方法,该方法有一个传入参数。方法名和传入的参数名可以任意定义。具体的业务逻辑就可以放在handle方法里面处理。

然后,在UserSubscribe类中添加subscribe方法,该方法传入参数为 Event 对象。然后在该方法中将监听的事件绑定到UserEvent类的handle方法上。如下:

?
1
$event->listen('testEvent', [app('app\event\UserEvent'), 'handle']);

完整代码如下

Other和Index类的代码跟第一种途径一样

UserSubscribe:事件订阅类

?
1
2
3
4
5
6
7
8
9
10
11
<?php
declare (strict_types = 1);
namespace app\subscribe;
use think\Event;
class UserSubscribe
{
    public function subscribe(Event $event)
    {
        $event->listen('testEvent', [app('app\event\UserEvent'), 'handle']);
    }
}

UserEvent:事件处理类

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?php
declare (strict_types = 1);
namespace app\event;
class UserEvent
{
    public function handle($user)
    {
        //当调用Index类的test1方法时该代码有效,$user为null
        var_dump($user);
        //当调用Index类的test2方法时该代码有效,$user为字符串hello
        var_dump($user);
        //当调用Index类的test3方法时该代码有效,$user为Index类的实例
        //可以访问Index类的name变量
        echo $user->name;
        //当调用Index类的test4方法时该代码有效,$user为Other类的实例
        //可以调用Other类的hello方法
        echo $user->hello();
    }
}

总结

1、通过监听的方式,每个事件都需要定义一个监听类来处理监听逻辑,并且在event.php的listen数组中配置

2、通过订阅的方式,如果采用自动绑定,则需要在订阅类中为每个事件定义一个监听方法(方法名不能自己定义),不需要定义subscribe方法;如果采用手动绑定,则定义subscribe方法,并为每一个事件绑定负责处理业务逻辑的具体方法(方法名可以自己定义)

3、通过监听的方式中,事件类基本上可有可无,因为创建的监听类本来就是专门处理对应的事件的业务逻辑的。并且监听类可以用事件类代替。

4、通过订阅的方式中,如果采用自动绑定,事件类也没有必要,因为在订阅类中为每个事件定义的监听方法本来就是专门处理对应的事件的业务逻辑的。如果采用手动绑定,也可以把监听方法写在订阅类中,那么事件类也就没必要了。但是个人认为手动绑定还是使用事件类比较好。订阅类只负责绑定,事件类负责处理具体业务逻辑,这样结构上比较清晰

5、其实通过监听的方式中,监听类(例子中的UserListener)可以替换成其他命名空间下的其他类,只要该类有一个handle方法就行,比如事件类。替换之后记得要在event.php配置文件中做对应修改。同理,通过订阅的方式中,也可以将订阅类(例子中的UserSubscribe)直接替换为其他类,但是要记得自动绑定需要在该类下有符合命名规则的方法,手动绑定需要在该类下有一个subscribe方法

以上就是Thinkphp事件机制两种实现方式详解的详细内容,更多关于Thinkphp事件机制的资料请关注服务器之家其它相关文章!

原文链接:https://blog.csdn.net/firstime_tzjz/article/details/126869156

延伸 · 阅读

精彩推荐
  • PHP教程PHP Undefined index报错的修复方法

    PHP Undefined index报错的修复方法

    用$_GET["xx"]这种形式取得数据时,如果之前不加判断,$_GET["xx"]不存在时会出现这样的警告:PHP Notice: undefined index xxx。 ...

    PHP教程网3892019-12-06
  • PHP教程php while循环控制的简单实例

    php while循环控制的简单实例

    下面小编就为大家带来一篇php while循环控制的简单实例。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧...

    PHP教程网4982021-01-24
  • PHP教程PHP 截取字符串专题集合

    PHP 截取字符串专题集合

    现在很多情况下,需要用到截取字符串功能,不够由于gb2312与utf-8的编码问题,需要区别对待,下面是具体的实现方法并从一些比较成熟的系统中扒下的代...

    php教程网2782019-11-07
  • PHP教程php操作mysql获取select 结果的几种方法

    php操作mysql获取select 结果的几种方法

    这篇文章主要介绍了php操作mysql获取select 结果的几种方法,需要的朋友可以参考下...

    xluren7482021-07-14
  • PHP教程PHP制作登录异常ip检测功能的实例代码

    PHP制作登录异常ip检测功能的实例代码

    下面小编就为大家带来一篇PHP制作登录异常ip检测功能的实例代码。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧...

    PHP教程网9512021-03-26
  • PHP教程PHP实现的简单日历类

    PHP实现的简单日历类

    这篇文章主要介绍了PHP实现的简单日历类,可实现简单的日期显示功能,并高亮标注当前日期,具有一定的实用价值,需要的朋友可以参考下...

    PHP教程网1722020-08-16
  • PHP教程php面向对象值单例模式

    php面向对象值单例模式

    一个对象(在学习设计模式之前,需要比较了解面向对象思想)只负责一个特定的任务,需要的朋友可以参考下...

    wulei10102021-01-13
  • PHP教程PHP数学运算与数据处理实例分析

    PHP数学运算与数据处理实例分析

    这篇文章主要介绍了PHP数学运算与数据处理方法,结合实例形式分析了PHP的数据类型与基本数学运算方法,需要的朋友可以参考下...

    phper5222021-01-07