事件系统 #

一、事件概述 #

1.1 什么是事件系统 #

事件系统实现了观察者模式,允许你订阅和监听应用中发生的各种事件。

text
事件系统组成
├── 事件(Event)
│   └── 发生的事情
├── 监听器(Listener)
│   └── 对事件的响应
└── 订阅者(Subscriber)
    └── 组织多个监听器

1.2 使用场景 #

text
事件系统使用场景
├── 发送通知
│   └── 用户注册后发送邮件
├── 记录日志
│   └── 记录用户操作
├── 数据同步
│   └── 同步到第三方服务
└── 清理缓存
    └── 数据更新后清除缓存

二、定义事件 #

2.1 创建事件 #

bash
php artisan make:event UserRegistered

2.2 事件类 #

php
// app/Events/UserRegistered.php
namespace App\Events;

use App\Models\User;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;

class UserRegistered
{
    use Dispatchable, SerializesModels;

    public $user;

    public function __construct(User $user)
    {
        $this->user = $user;
    }
}

三、定义监听器 #

3.1 创建监听器 #

bash
php artisan make:listener SendWelcomeEmail --event=UserRegistered

3.2 监听器类 #

php
// app/Listeners/SendWelcomeEmail.php
namespace App\Listeners;

use App\Events\UserRegistered;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;

class SendWelcomeEmail implements ShouldQueue
{
    public function handle(UserRegistered $event)
    {
        $event->user->sendWelcomeEmail();
    }
}

3.3 队列监听器 #

php
class SendWelcomeEmail implements ShouldQueue
{
    use InteractsWithQueue;
    
    public $delay = 60; // 延迟60秒
    
    public $tries = 3; // 重试3次
    
    public function handle(UserRegistered $event)
    {
        // ...
    }
    
    public function failed(UserRegistered $event, $exception)
    {
        // 处理失败
    }
}

四、注册事件和监听器 #

4.1 在EventServiceProvider注册 #

php
// app/Providers/EventServiceProvider.php
protected $listen = [
    UserRegistered::class => [
        SendWelcomeEmail::class,
        LogUserRegistration::class,
    ],
    
    OrderShipped::class => [
        SendShipmentNotification::class,
    ],
];

4.2 自动发现 #

php
// app/Providers/EventServiceProvider.php
public function shouldDiscoverEvents()
{
    return true;
}

protected function discoverEventsWithin()
{
    return [
        app_path('Listeners'),
    ];
}

五、分发事件 #

5.1 使用事件辅助函数 #

php
use App\Events\UserRegistered;

event(new UserRegistered($user));

5.2 使用事件静态方法 #

php
UserRegistered::dispatch($user);

5.3 使用事件分发器 #

php
use Illuminate\Support\Facades\Event;

Event::dispatch(new UserRegistered($user));

六、事件订阅者 #

6.1 创建订阅者 #

php
// app/Listeners/UserEventSubscriber.php
namespace App\Listeners;

use Illuminate\Events\Dispatcher;

class UserEventSubscriber
{
    public function handleUserLogin($event)
    {
        // 处理用户登录
    }

    public function handleUserLogout($event)
    {
        // 处理用户登出
    }

    public function subscribe(Dispatcher $events)
    {
        $events->listen(
            'Illuminate\Auth\Events\Login',
            [UserEventSubscriber::class, 'handleUserLogin']
        );

        $events->listen(
            'Illuminate\Auth\Events\Logout',
            [UserEventSubscriber::class, 'handleUserLogout']
        );
    }
}

6.2 注册订阅者 #

php
// app/Providers/EventServiceProvider.php
protected $subscribe = [
    UserEventSubscriber::class,
];

七、模型事件 #

7.1 模型事件类型 #

事件 说明
retrieved 从数据库获取后
creating 创建前
created 创建后
updating 更新前
updated 更新后
saving 保存前
saved 保存后
deleting 删除前
deleted 删除后
restoring 恢复前
restored 恢复后

7.2 在模型中定义 #

php
class User extends Model
{
    protected static function booted()
    {
        static::created(function ($user) {
            event(new UserRegistered($user));
        });
        
        static::updating(function ($user) {
            // 更新前
        });
    }
}

7.3 使用Observer #

bash
php artisan make:observer UserObserver --model=User
php
// app/Observers/UserObserver.php
class UserObserver
{
    public function created(User $user)
    {
        event(new UserRegistered($user));
    }

    public function updated(User $user)
    {
        // 更新后
    }

    public function deleted(User $user)
    {
        // 删除后
    }
}

// 注册
// app/Providers/AppServiceProvider.php
public function boot()
{
    User::observe(UserObserver::class);
}

八、停止事件传播 #

8.1 返回false #

php
public function handle(UserRegistered $event)
{
    if ($event->user->isBlocked()) {
        return false; // 停止传播
    }
    
    // 继续处理
}

九、实战示例 #

9.1 订单事件 #

php
// 事件
class OrderPaid
{
    use Dispatchable, SerializesModels;

    public $order;

    public function __construct(Order $order)
    {
        $this->order = $order;
    }
}

// 监听器
class SendOrderNotification
{
    public function handle(OrderPaid $event)
    {
        Mail::to($event->order->user)->send(new OrderPaidMail($event->order));
    }
}

class UpdateInventory
{
    public function handle(OrderPaid $event)
    {
        foreach ($event->order->items as $item) {
            $item->product->decrement('stock', $item->quantity);
        }
    }
}

class RecordTransaction
{
    public function handle(OrderPaid $event)
    {
        Transaction::create([
            'order_id' => $event->order->id,
            'amount' => $event->order->total,
        ]);
    }
}

// 注册
protected $listen = [
    OrderPaid::class => [
        SendOrderNotification::class,
        UpdateInventory::class,
        RecordTransaction::class,
    ],
];

// 分发
event(new OrderPaid($order));

十、总结 #

10.1 核心概念 #

概念 说明
Event 事件类
Listener 监听器类
Subscriber 订阅者类
Observer 模型观察者

10.2 下一步 #

掌握了事件系统后,让我们继续学习 任务队列,了解Laravel队列系统!

最后更新:2026-03-28