Laravel 模型事件(Model Events)
Laravel 的模型事件(Model Events)是 Eloquent ORM 提供的一种机制,允许你在模型生命周期的关键节点自动触发逻辑。这些节点包括创建、更新、删除、恢复、保存等操作,适合用于解耦业务逻辑、数据同步、日志记录、权限控制等场景。
✅ 一、模型事件的完整列表
| 事件名称 | 触发时机说明 |
|---|---|
retrieved |
模型从数据库中读取后触发 |
creating |
模型即将被创建(保存前) |
created |
模型已被创建(保存后) |
updating |
模型即将被更新(保存前) |
updated |
模型已被更新(保存后) |
saving |
模型即将被保存(创建或更新前) |
saved |
模型已被保存(创建或更新后) |
deleting |
模型即将被删除 |
deleted |
模型已被删除 |
restoring |
软删除模型即将被恢复 |
restored |
软删除模型已被恢复 |
forceDeleting |
模型即将被强制删除 |
forceDeleted |
模型已被强制删除 |
replicating |
模型正在被复制 |
注意:以ing结尾的事件在操作前触发,以ed结尾的事件在操作后触发。
✅ 二、使用方式详解
✅ 1. 在模型中注册闭包(推荐简单场景)
class User extends Model
{
protected static function booted()
{
static::created(function ($user) {
\Log::info("用户 {$user->name} 已创建");
});
static::updated(function ($user) {
\Log::info("用户 {$user->name} 已更新");
});
static::deleting(function ($user) {
if ($user->isAdmin()) {
return false; // 阻止删除
}
});
}
}
在creating、updating、saving、deleting中返回false可中断操作。
✅ 2. 使用 $dispatchesEvents 映射到自定义事件类(推荐复杂场景)
class User extends Model
{
protected $dispatchesEvents = [
'created' => UserCreated::class,
'updated' => UserUpdated::class,
'deleted' => UserDeleted::class,
];
}
自定义事件类示例:
namespace App\Events;
use App\Models\User;
use Illuminate\Foundation\Events\Dispatchable;
class UserCreated
{
use Dispatchable;
public $user;
public function __construct(User $user)
{
$this->user = $user;
}
}
监听器示例(在
EventServiceProvider 中注册):protected $listen = [
\App\Events\UserCreated::class => [
\App\Listeners\SendWelcomeEmail::class,
],
];
✅ 3. 使用模型观察者(Observer)统一管理
class UserObserver
{
public function created(User $user)
{
Mail::to($user->email)->send(new WelcomeMail($user));
}
public function updated(User $user)
{
Cache::forget("user.{$user->id}");
}
}
注册观察者:
// 在 AppServiceProvider 或 EventServiceProvider 中
User::observe(UserObserver::class);
✅ 三、实际应用场景举例
| 场景 | 示例代码 |
|---|---|
| 发送欢迎邮件 | User::created(fn($u) => Mail::to($u->email)->send(new WelcomeMail($u))); |
| 数据同步 | User::updated(fn($u) => ExternalAPI::sync($u)); |
| 日志记录 | User::saved(fn($u) => ActivityLog::log($u)); |
| 权限刷新 | User::updated(fn($u) => $u->isDirty('role_id') && $u->syncPermissions()); |
| 缓存清理 | User::updated(fn($u) => Cache::forget("user.{$u->id}")); |
⚠️ 四、注意事项与最佳实践
-
事务中的事件:模型事件在事务中也会被触发,但不会等待事务提交。若需事务一致性,可使用数据库事务监听器或延迟任务。
-
避免副作用:模型事件是自动触发的,滥用可能导致难以追踪的副作用,建议将复杂逻辑提取到事件类或观察者中。
-
测试时禁用事件:使用
Model::withoutEvents()或Event::fake()避免测试中触发事件。
✅ 五、总结一句话
Laravel 的模型事件是一个解耦、自动化、可扩展的工具,适合在模型生命周期中插入通用逻辑,但需谨慎设计,避免逻辑混乱。
如需更高级的关系事件(如一对多、多对多关联的 attach/detach/sync 等),可引入扩展包如 Laravel Relationship Events。
本文来自博客园,作者:Carvers,转载请注明原文链接:https://www.cnblogs.com/carver/articles/19020184

浙公网安备 33010602011771号