Laravel 13 事件系统详解
摘要
Laravel 的事件系统提供了观察者模式的实现,允许订阅和监听应用中的事件。本文将深入讲解 Laravel 13 的事件系统,包括:
- 事件与监听器
- 事件订阅者
- 队列处理
- 模型事件
- 实战案例与最佳实践
本文适合希望掌握事件系统的 Laravel 开发者。
1. 创建事件与监听器
1.1 生成事件
1
| php artisan make:event OrderShipped
|
1.2 事件类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| <?php
namespace App\Events;
use Illuminate\Foundation\Events\Dispatchable; use Illuminate\Queue\SerializesModels; use App\Models\Order;
class OrderShipped { use Dispatchable, SerializesModels; public function __construct( public Order $order ) {} }
|
1.3 生成监听器
1
| php artisan make:listener SendShipmentNotification --event=OrderShipped
|
1.4 监听器类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| <?php
namespace App\Listeners;
use App\Events\OrderShipped; use Illuminate\Contracts\Queue\ShouldQueue;
class SendShipmentNotification implements ShouldQueue { public function handle(OrderShipped $event): void { $event->order->user->notify(new OrderShippedNotification($event->order)); } }
|
2. 注册事件
2.1 在 EventServiceProvider 注册
1 2 3 4 5 6 7
| protected $listen = [ OrderShipped::class => [ SendShipmentNotification::class, UpdateInventory::class, ], ];
|
2.2 自动发现
1 2 3 4 5
| 'events' => [ 'discover' => true, 'paths' => [app_path('Listeners')], ],
|
3. 分发事件
3.1 使用事件辅助函数
1 2 3
| use App\Events\OrderShipped;
event(new OrderShipped($order));
|
3.2 使用事件静态方法
1
| OrderShipped::dispatch($order);
|
4. 队列监听器
4.1 实现队列
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| class SendShipmentNotification implements ShouldQueue { use InteractsWithQueue; public function handle(OrderShipped $event): void { } public function failed(OrderShipped $event, Throwable $exception): void { } }
|
4.2 配置队列
1 2 3 4 5 6 7
| class SendShipmentNotification implements ShouldQueue { public $queue = 'notifications'; public $delay = 60; public $tries = 3; public $backoff = [10, 30, 60]; }
|
5. 事件订阅者
5.1 创建订阅者
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| <?php
namespace App\Listeners;
use Illuminate\Events\Dispatcher;
class UserEventSubscriber { public function handleUserCreated($event): void { } public function handleUserDeleted($event): void { } public function subscribe(Dispatcher $events): array { return [ UserCreated::class => 'handleUserCreated', UserDeleted::class => 'handleUserDeleted', ]; } }
|
5.2 注册订阅者
1 2 3 4
| protected $subscribe = [ UserEventSubscriber::class, ];
|
6. 模型事件
6.1 模型事件监听
1 2 3 4 5 6 7 8 9 10 11 12 13
| use App\Models\User;
User::created(function ($user) { });
User::updated(function ($user) { });
User::deleted(function ($user) { });
|
6.2 在模型中定义
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| class User extends Model { protected static function booted() { static::creating(function ($user) { $user->api_token = Str::random(60); }); static::updating(function ($user) { if ($user->isDirty('email')) { $user->email_verified_at = null; } }); } }
|
7. 实战案例
7.1 订单处理事件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| <?php
namespace App\Events;
use Illuminate\Foundation\Events\Dispatchable; use Illuminate\Queue\SerializesModels; use App\Models\Order;
class OrderPlaced { use Dispatchable, SerializesModels; public function __construct( public Order $order ) {} }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| <?php
namespace App\Listeners;
use App\Events\OrderPlaced; use Illuminate\Contracts\Queue\ShouldQueue; use App\Services\InventoryService; use App\Notifications\OrderConfirmation;
class ProcessOrder implements ShouldQueue { public function __construct( protected InventoryService $inventory ) {} public function handle(OrderPlaced $event): void { $order = $event->order; $this->inventory->decrement($order); $order->user->notify(new OrderConfirmation($order)); Log::info('Order processed', ['order_id' => $order->id]); } }
|
8. 最佳实践
8.1 命名规范
1 2 3 4 5 6 7 8 9
| OrderShipped UserCreated PaymentProcessed
ShipOrder CreateUser ProcessPayment
|
8.2 使用队列
1 2 3 4 5
| class SendNotification implements ShouldQueue { }
|
9. 总结
Laravel 的事件系统提供了强大的事件驱动能力:
- 解耦代码:事件与监听器分离
- 队列支持:异步处理事件
- 模型事件:自动触发模型事件
- 订阅者:批量订阅事件
参考资料