Loading

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; // 阻止删除
            }
        });
    }
}
creatingupdatingsavingdeleting 中返回 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
posted @ 2025-08-03 16:13  Carvers  阅读(31)  评论(0)    收藏  举报