[笔记] hyperf event

事件

模型事件实现于 psr/event-dispatcher 接口。

自定义监听器

得益于 hyperf/event 组件的支撑,用户可以很方便的对以下事件进行监听。例如 QueryExecuted , StatementPrepared , TransactionBeginning , TransactionCommitted , TransactionRolledBack 。接下来我们就实现一个记录SQL的监听器,来说一下怎么使用。首先我们定义好 DbQueryExecutedListener ,实现 Hyperf\Event\Contract\ListenerInterface 接口并对类定义 Hyperf\Event\Annotation\Listener 注解,这样 Hyperf 就会自动把该监听器注册到事件调度器中,无需任何手动配置,示例代码如下:

复制代码
<?php
declare(strict_types=1);
namespace App\Listeners;
use Hyperf\Database\Events\QueryExecuted;
use Hyperf\Event\Annotation\Listener;
use Hyperf\Event\Contract\ListenerInterface;
use Hyperf\Logger\LoggerFactory;
use Hyperf\Utils\Arr;
use Hyperf\Utils\Str;
use Psr\Container\ContainerInterface;
use Psr\Log\LoggerInterface;
/**
 * @Listener
 */
class DbQueryExecutedListener implements ListenerInterface
{
    /**
     * @var LoggerInterface
     */
    private $logger;
    public function __construct(LoggerFactory $loggerFactory)
    {
        $this->logger = $loggerFactory->get('sql');
    }
    public function listen(): array
    {
        return [
            QueryExecuted::class,
        ];
    }
    /**
     * @param QueryExecuted $event
     */
    public function process(object $event)
    {
        if ($event instanceof QueryExecuted) {
            $sql = $event->sql;
            if (! Arr::isAssoc($event->bindings)) {
                foreach ($event->bindings as $key => $value) {
                    $sql = Str::replaceFirst('?', "'{$value}'", $sql);
                }
            }
            $this->logger->info(sprintf('[%s] %s', $event->time, $sql));
        }
    }
}

模型事件

模型事件与 EloquentORM 不太一致,EloquentORM 使用 Observer 监听模型事件。Hyperf 直接使用 钩子函数 来处理对应的事件。如果你还是喜欢 Observer 的方式,可以通过 事件监听,自己实现。当然,你也可以在 issue#2 下面告诉我们。

钩子函数

事件名 触发实际 是否阻断 备注
booting 模型首次加载前 进程生命周期中只会触发一次
booted 模型首次加载后 进程生命周期中只会触发一次
retrieved 填充数据后 每当模型从DB或缓存查询出来后触发
creating 数据创建时
created 数据创建后
updating 数据更新时
updated 数据更新后
saving 数据创建或更新时
saved 数据创建或更新后
restoring 软删除数据回复时
restored 软删除数据回复后
deleting 数据删除时
deleted 数据删除后
forceDeleted 数据强制删除后

针对某个模型的事件使用十分简单,只需要在模型中增加对应的方法即可。例如下方保存数据时,触发 saving 事件,主动覆写 created_at 字段。

复制代码
<?php
declare(strict_types=1);
namespace App\Models;
use Hyperf\Database\Model\Events\Saving;
/**
 * @property $id
 * @property $name
 * @property $gender
 * @property $created_at
 * @property $updated_at
 */
class User extends Model
{
    /**
     * The table associated with the model.
     *
     * @var string
     */
    protected $table = 'user';
    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = ['id', 'name', 'gender', 'created_at', 'updated_at'];
    protected $casts = ['id' => 'integer', 'gender' => 'integer'];
    public function saving(Saving $event)
    {
        $this->setCreatedAt('2019-01-01');
    }
}

事件监听

当你需要监听所有的模型事件时,可以很方便的自定义对应的 Listener,比如下方模型缓存的监听器,当模型修改和删除后,会删除对应缓存。

复制代码
<?php
declare(strict_types=1);
namespace Hyperf\ModelCache\Listener;
use Hyperf\Database\Model\Events\Deleted;
use Hyperf\Database\Model\Events\Event;
use Hyperf\Database\Model\Events\Saved;
use Hyperf\Event\Annotation\Listener;
use Hyperf\Event\Contract\ListenerInterface;
use Hyperf\ModelCache\CacheableInterface;
/**
 * @Listener
 */
class DeleteCacheListener implements ListenerInterface
{
    public function listen(): array
    {
        return [
            Deleted::class,
            Saved::class,
        ];
    }
    public function process(object $event)
    {
        if ($event instanceof Event) {
            $model = $event->getModel();
            if ($model instanceof CacheableInterface) {
                $model->deleteCache();
            }
        }
    }
}
相关推荐
guodingdingh23 分钟前
软件开发工作问题总结0718
java·开发语言·数据库
咖啡八杯2 小时前
GoF设计模式——解释器模式
java·后端·spring·设计模式
优橙教育2 小时前
5G网优培训 vs Java开发:转行选哪个?
java·开发语言·5g
掘金码甲哥2 小时前
这块终端神器, 必须吹爆!
后端
糖果店的幽灵2 小时前
【DeepAgents 从入门到精通】Context Management 上下文管理
java·人工智能·后端·spring·中间件·langgraph·deepagents
Csvn3 小时前
📊 SQL 入门 Day 8:集合操作 — 用 SQL 做数学里的"并交差"
后端·sql
腻害兔4 小时前
【若依项目-产品经理视角】RuoYi-Vue-Pro 源码拆解:字典、短信、邮件、通知——后台系统的“基础设施四件套“!
java·前端·vue.js·产品经理·ai编程
碎光拾影4 小时前
ARM交叉工具链各工具作用及IMX6ULL平台LED+蜂鸣器裸机程序实现
java·开发语言·数据库
Miao121315 小时前
微服务 API 测试实践:海外某民宿平台如何构建模式驱动测试基础设施
java·开发语言
腻害兔5 小时前
【若依项目-产品经理视角】RuoYi-Vue-Pro 源码拆解:支付模块 yudao-module-pay,一个让产品经理都看懂的支付中台设计
java·前端·vue.js·产品经理·ai编程