首页 php框架 ThinkPHP ThinkPHP6.0:事件系统以及查询事件、模型事件的使用

ThinkPHP6.0:事件系统以及查询事件、模型事件的使用

Dec 16, 2019 pm 02:19 PM
事件系统 模型事件

ThinkPHP6.0:事件系统以及查询事件、模型事件的使用

在最新的6.0版本中引入了新的事件系统用以替代5.1版本的行为,同时也接管了数据库事件和模型事件。

本篇主要描述下新版的事件系统以及查询事件、模型事件的使用。

定义事件

事件系统的所有操作都通过think\facade\Event类进行静态调用

事件系统使用了观察者模式,提供了解耦应用的更好方式。在你需要监听事件的位置,添加如下代码:

Event::trigger('UserLogin');
登录后复制

或者使用助手函数

event('UserLogin');
登录后复制

这里UserLogin表示一个事件标识,如果你定义了单独的事件类,你可以使用事件类名,甚至可以传入一个事件类实例。

event('app\event\UserLogin');
登录后复制

事件类可以通过命令行快速生成

php think make:event UserLogin
登录后复制

默认会生成一个app\event\UserLogin事件类,也可以指定完整类名生成。

我们可以给事件类添加方法

namespace app\event;
use app\model\User;
class UserLogin
{
    public $user;
    public function __construct(User $user)
    {
        $this->user = $user;
    }
}
登录后复制

一般事件类无需继承任何其它类。

你可以给事件类绑定一个事件标识

Event::bind('UserLogin', 'app\event\UserLogin');
登录后复制

或者在应用的event.php事件定义文件中批量绑定。

return [
    'bind'    =>    [
        'UserLogin' => 'app\event\UserLogin',
        // 更多事件绑定
    ],
];
登录后复制

如果你没有定义事件类的话,则无需绑定。

ThinkPHP的事件系统不依赖事件类,如果没有额外的需求,仅通过事件标识也可以使用。

你可以在event方法中传入一个事件参数

event('UserLogin', $user);
登录后复制

事件监听

你可以手动注册一个事件监听

Event::listen('UserLogin', function($user) {
    // 
});
登录后复制

或者使用监听类

Event::listen('UserLogin', 'app\listener\UserLogin');
登录后复制

可以通过命令行快速生成一个事件监听类

php think make:listener UserLogin
登录后复制

默认会生成一个app\listener\UserLogin事件监听类,也可以指定完整类名生成。

事件监听类只需要定义一个handler方法,支持依赖注入。

<?php
namespace app\listener;
class UserLogin
{
    public function handle($user)
    {
        // 事件监听处理
    }   
}
登录后复制

在handler方法中如果返回了false,则表示监听中止,将不再执行该事件后面的监听。

一般建议直接在事件定义文件中定义对应事件的监听。

return [
    &#39;bind&#39;    =>    [
        &#39;UserLogin&#39; => &#39;app\event\UserLogin&#39;,
        // 更多事件绑定
    ],
    &#39;listen&#39;  =>    [
        &#39;UserLogin&#39;    =>    [&#39;\app\listener\UserLogin&#39;],
        // 更多事件监听
    ],
];
登录后复制

事件订阅

可以通过事件订阅机制,在一个监听器中监听多个事件,例如通过命令行生成一个事件订阅者类,

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(&#39;app\subscribe\User&#39;);
登录后复制

一般建议直接在事件定义文件中定义

return [
    &#39;bind&#39;    =>    [
        &#39;UserLogin&#39; => &#39;app\event\UserLogin&#39;,
        // 更多事件绑定
    ],
    &#39;listen&#39;  =>    [
        &#39;UserLogin&#39;    =>    [&#39;\app\listener\UserLogin&#39;],
        // 更多事件监听
    ],
    &#39;subscribe&#39;    =>    [
       &#39;\app\subscribe\User&#39;,
        // 更多事件订阅
    ],
];
登录后复制

内置事件

内置的系统事件包括:

1576476349917050.png

AppInit事件定义必须在全局事件定义文件中定义,其它事件支持在应用的事件定义文件中定义。

原来5.1的一些行为标签已经废弃,所有取消的标签都可以使用中间件更好的替代。可以把中间件看成处理请求以及响应输出相关的特殊事件。事实上,中间件的handle方法只是具有特殊的参数以及返回值而已。

查询事件

数据库操作的回调也称为查询事件,是针对数据库的CURD操作而设计的回调方法,主要包括:

1576476293220136.png

使用下面的方法注册数据库查询事件

\think\facade\Db::event(&#39;before_select&#39;, function ($query) {
    // 事件处理
    return $result;
});
登录后复制

同一个查询事件可以注册多个响应执行。查询事件在新版里面也已经被事件系统接管了,因此如果你注册了一个before_select查询事件监听,底层其实是向标识为db.before_select的事件注册了一个监听。

查询事件的方法参数只有一个:当前的查询对象。但你可以通过依赖注入的方式添加额外的参数。

模型事件

模型事件是指在进行模型的查询和写入操作的时候触发的操作行为。

模型事件只在调用模型的方法生效,使用查询构造器操作是无效的。

模型支持如下事件:

1576476181857690.png

注册的回调方法支持传入一个参数(当前的模型对象实例),但支持依赖注入的方式增加额外参数。

如果before_write、before_insert、 before_update 、before_delete事件方法中返回false或者抛出think\exception\

ModelEventException异常的话,则不会继续执行后续的操作。

模型事件定义

最简单的方式是在模型类里面定义静态方法来定义模型的相关事件响应。

<?php
namespace app\index\model;
use think\Model;
use app\index\model\Profile;
class User extends Model
{
    public static function onBeforeUpdate($user)
    {
    if (&#39;thinkphp&#39; == $user->name) {
        return false;
        }
    }
    
    public static function onAfterDelete($user)
    {
Profile::destroy($user->id);
    }
}
登录后复制

参数是当前的模型对象实例,支持使用依赖注入传入更多的参数。

模型事件观察者

如果希望模型的事件单独管理,可以给模型注册一个事件观察者,例如:

<?php
namespace app\index\model;
use think\Model;
class User extends Model
{
    protected $observerClass = &#39;app\index\observer\User&#39;;
}
登录后复制

User观察者类定义如下:

<?php
namespace app\index\observer;
use app\index\model\Profile;
class User
{
    public function onBeforeUpdate($user)
    {
    if (&#39;thinkphp&#39; == $user->name) {
        return false;
        }
    }
    
    public function onAfterDelete($user)
    {
Profile::destroy($user->id);
    }
}
登录后复制

观察者类的事件响应方法的第一个参数就是模型对象实例,你依然可以通过依赖注入传入其它的对象参数。

PHP中文网,大量的免费ThinkPHP入门教程,欢迎在线学习!

本文转自:https://blog.thinkphp.cn/1037387

以上是ThinkPHP6.0:事件系统以及查询事件、模型事件的使用的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
4 周前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
4 周前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您听不到任何人,如何修复音频
4 周前 By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解锁Myrise中的所有内容
1 个月前 By 尊渡假赌尊渡假赌尊渡假赌

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

在无服务器体系结构中使用ThinkPHP的关键注意事项是什么? 在无服务器体系结构中使用ThinkPHP的关键注意事项是什么? Mar 18, 2025 pm 04:54 PM

本文讨论了在无服务器体系结构中使用ThinkPHP的关键注意事项,专注于性能优化,无状态设计和安全性。它突出了诸如成本效率和可扩展性之类的收益,但也应对挑战

ThinkPHP依赖性注入容器的高级功能是什么? ThinkPHP依赖性注入容器的高级功能是什么? Mar 18, 2025 pm 04:50 PM

ThinkPHP的IOC容器提供了高级功能,例如懒惰加载,上下文绑定和方法注入PHP App中有效依赖性管理的方法。Character计数:159

ThinkPHP内置测试框架的关键功能是什么? ThinkPHP内置测试框架的关键功能是什么? Mar 18, 2025 pm 05:01 PM

本文讨论了ThinkPHP的内置测试框架,突出了其关键功能(例如单元和集成测试),以及它如何通过早期的错误检测和改进的代码质量来增强应用程序可靠性。

如何在ThinkPHP微服务中实现服务发现和负载平衡? 如何在ThinkPHP微服务中实现服务发现和负载平衡? Mar 18, 2025 pm 04:51 PM

本文讨论了在ThinkPHP微服务中实施服务发现和负载平衡,重点是设置,最佳实践,集成方法和推荐工具。[159个字符]

如何使用ThinkPHP和RabbitMQ构建分布式任务队列系统? 如何使用ThinkPHP和RabbitMQ构建分布式任务队列系统? Mar 18, 2025 pm 04:45 PM

本文概述了使用ThinkPhp和RabbitMQ构建分布式任务队列系统,重点是安装,配置,任务管理和可扩展性。关键问题包括确保高可用性,避免常见的陷阱,例如不当

在ThinkPHP中处理文件上传和云存储的最佳方法是什么? 在ThinkPHP中处理文件上传和云存储的最佳方法是什么? Mar 17, 2025 pm 02:28 PM

本文讨论了处理文件上传和集成在ThinkPhp中的云存储的最佳实践,重点是安全性,效率和可扩展性。

如何使用ThinkPHP来构建实时股票市场数据源? 如何使用ThinkPHP来构建实时股票市场数据源? Mar 18, 2025 pm 04:57 PM

文章讨论了使用ThinkPHP进行实时股票市场数据提要,重点是设置,数据准确性,优化和安全措施。

如何使用ThinkPHP来构建实时协作工具? 如何使用ThinkPHP来构建实时协作工具? Mar 18, 2025 pm 04:49 PM

本文讨论了使用ThinkPHP来构建实时协作工具,重点关注设置,Websocket集成和安全性最佳实践。

See all articles