本文目录导读:

在 Laravel 中,模型观察者(Observer) 是一种监听模型生命周期事件(如 created、updated、deleted 等)的优雅方式,它允许你将相关的事件处理逻辑集中在一个类中,避免在模型本身或控制器中散布这些逻辑。
基本概念
Laravel 模型会触发多个事件,常见的包括:
retrieved:从数据库检索到模型后creating/created:创建模型之前 / 之后updating/updated:更新模型之前 / 之后saving/saved:保存模型(创建或更新)之前 / 之后deleting/deleted:删除模型之前 / 之后restoring/restored:软删除模型恢复之前 / 之后
创建观察者
使用 Artisan 命令(推荐)
可以用 make:observer 命令快速生成观察者类:
php artisan make:observer UserObserver --model=User
这将在 app/Observers/UserObserver.php 创建观察者类,并自动绑定到 User 模型。
手动创建
也可以手动创建 app/Observers/UserObserver.php:
<?php
namespace App\Observers;
use App\Models\User;
class UserObserver
{
public function created(User $user)
{
// 用户创建后的逻辑
\Log::info('新用户注册: ' . $user->email);
}
public function updated(User $user)
{
// 用户更新后的逻辑
\Log::info('用户信息更新: ' . $user->email);
}
public function deleting(User $user)
{
// 用户删除前的逻辑(比如检查是否可以删除)
if ($user->isAdmin()) {
return false; // 阻止删除操作
}
}
}
注册观察者
在服务提供者中注册(推荐)
通常在 AppServiceProvider 或专门的 EventServiceProvider 中注册:
<?php
namespace App\Providers;
use App\Models\User;
use App\Observers\UserObserver;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
public function boot()
{
User::observe(UserObserver::class);
}
}
在模型的 boot() 方法中注册
<?php
namespace App\Models;
use App\Observers\UserObserver;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
protected static function boot()
{
parent::boot();
static::observe(UserObserver::class);
}
}
完整示例
假设我们有一个 Order 模型,希望在订单创建后发送通知,在订单删除前检查状态:
1) 创建观察者
php artisan make:observer OrderObserver --model=Order
2) 编写逻辑
<?php
namespace App\Observers;
use App\Models\Order;
use App\Notifications\OrderCreated;
use Illuminate\Support\Facades\Notification;
class OrderObserver
{
public function created(Order $order)
{
// 发送通知给管理员
Notification::route('mail', 'admin@example.com')
->notify(new OrderCreated($order));
}
public function deleting(Order $order)
{
// 如果订单已发货,禁止删除
if ($order->status === 'shipped') {
return false;
}
}
}
3) 注册观察者
// AppServiceProvider.php
public function boot()
{
Order::observe(OrderObserver::class);
}
观察者中的返回值影响
观察者方法可以返回 false 来阻止事件继续执行:
public function creating(Order $order)
{
if ($order->total <= 0) {
return false; // 阻止创建
}
}
常用事件与方法对照
| 事件 | 观察者方法 | 触发时机 |
|---|---|---|
retrieved |
retrieved |
查询到模型后 |
creating |
creating |
创建之前 |
created |
created |
创建之后 |
updating |
updating |
更新之前 |
updated |
updated |
更新之后 |
saving |
saving |
保存之前 |
saved |
saved |
保存之后 |
deleting |
deleting |
删除之前 |
deleted |
deleted |
删除之后 |
restoring |
restoring |
软删除恢复之前 |
restored |
restored |
软删除恢复之后 |
最佳实践
- 职责单一:一个观察者只负责一个模型的事件
- 避免复杂逻辑:观察者中不要写太重的业务逻辑,建议调用服务类
- 使用队列:如果观察者中包含耗时操作(如发送邮件),建议使用队列
- 适当命名:观察者方法名与事件名一致,方便理解
- 谨慎使用
return false:阻止操作可能会带来意想不到的副作用
观察者让模型事件处理更加清晰、可维护,是 Laravel 项目中常用且推荐的做法。