PHP项目Laravel事件监听使用场景

wen PHP项目 6

本文目录导读:

PHP项目Laravel事件监听使用场景

  1. 数据变更通知
  2. 业务日志记录
  3. 缓存同步
  4. 支付流程处理
  5. 第三方服务集成
  6. 队列处理(异步任务)
  7. 实时通知(WebSocket/Pusher)
  8. 多步骤业务处理
  9. 用户行为追踪
  10. 权限和认证
  11. 最佳实践建议

在 Laravel 中,事件监听是一个强大且灵活的解耦机制,以下是主要的使用场景,分为几大类:

数据变更通知

用户注册后通知

// 事件
class UserRegistered
{
    public $user;
    public function __construct(User $user)
    {
        $this->user = $user;
    }
}
// 多个监听器
class SendWelcomeEmail
{
    public function handle(UserRegistered $event)
    {
        Mail::to($event->user->email)->send(new WelcomeEmail($event->user));
    }
}
class SendAdminNotification
{
    public function handle(UserRegistered $event)
    {
        // 通知管理员有用户注册
        AdminNotification::create([
            'message' => 'New registration: ' . $event->user->email
        ]);
    }
}

业务日志记录

class ProductService
{
    public function update(Product $product, array $data)
    {
        $original = $product->getOriginal();
        $product->update($data);
        // 触发事件,记录变更
        event(new ProductUpdated($product, $original));
    }
}
// 监听器记录日志
class LogProductChanges
{
    public function handle(ProductUpdated $event)
    {
        activity()
            ->performedOn($event->product)
            ->withProperties([
                'old' => $event->original,
                'new' => $event->product->getAttributes()
            ])
            ->log('Product updated');
    }
}

缓存同步

class ProductController extends Controller
{
    public function update(Request $request, Product $product)
    {
        $product->update($request->validated());
        // 清除相关缓存
        event(new ProductUpdated($product));
        return redirect()->back();
    }
}
// 监听器
class ClearProductCaches
{
    public function handle(ProductUpdated $event)
    {
        Cache::forget('product_' . $event->product->id);
        Cache::forget('best_selling_products');
    }
}

支付流程处理

// 支付成功事件
class PaymentSucceeded
{
    public $order;
    public $transaction;
    public function __construct(Order $order, Payment $transaction)
    {
        $this->order = $order;
        $this->transaction = $transaction;
    }
}
// 多个监听器,按顺序执行
class UpdateOrderStatus
{
    public function handle(PaymentSucceeded $event)
    {
        $event->order->update(['status' => 'paid']);
    }
}
class SendInvoiceEmail
{
    public function handle(PaymentSucceeded $event)
    {
        // 生成并发送发票
    }
}
class UpdateInventory
{
    public function handle(PaymentSucceeded $event)
    {
        // 扣减库存
    }
}
// 注册监听器顺序
Event::listen(
    PaymentSucceeded::class,
    [
        UpdateOrderStatus::class,
        SendInvoiceEmail::class,
        UpdateInventory::class,
    ]
);

第三方服务集成

class OrderShipped
{
    public $order;
    public function __construct(Order $order)
    {
        $this->order = $order;
    }
}
// 不同监听器处理不同的第三方服务
class SyncToErp
{
    public function handle(OrderShipped $event)
    {
        // 同步订单到 ERP 系统
        $erpService->syncOrder($event->order);
    }
}
class SyncToReporting
{
    public function handle(OrderShipped $event)
    {
        // 同步到报表系统
        MetricsService::trackOrder($event->order);
    }
}
class UpdateTrackingSystem
{
    public function handle(OrderShipped $event)
    {
        // 更新物流追踪系统
        TrackingAPI::updateStatus($event->order->tracking_number);
    }
}

队列处理(异步任务)

// 事件监听器实现 ShouldQueue 接口
class SendOrderConfirmation implements ShouldQueue
{
    use InteractsWithQueue;
    public $timeout = 60;
    public $tries = 3;
    public function handle(OrderPlaced $event)
    {
        // 发送订单确认
        Mail::to($event->order->customer)
            ->send(new OrderConfirmation($event->order));
    }
    public function failed(OrderPlaced $event, $exception)
    {
        // 处理失败情况
        Log::error('Order confirmation failed');
    }
}

实时通知(WebSocket/Pusher)

class SendRealtimeNotification
{
    public function handle(NewReview $event)
    {
        broadcast(new NewReviewNotification($event->review))->toOthers();
        // 推送实时通知
        event(new NotificationEvent(
            Auth::user()->id,
            'New review posted'
        ));
    }
}

多步骤业务处理

class OrderCancellation
{
    public $order;
    public $reason;
    public function __construct(Order $order, string $reason)
    {
        $this->order = $order;
        $this->reason = $reason;
    }
}
// 监听器按顺序处理
class ProcessRefund
{
    public function handle(OrderCancellation $event)
    {
        $event->order->refund();
    }
}
class EmailCustomer
{
    public function handle(OrderCancellation $event)
    {
        Mail::to($event->order->customer)
            ->send(new CancellationNotification($event->order, $event->reason));
    }
}
class NotifySupport
{
    public function handle(OrderCancellation $event)
    {
        SupportTeam::createTicket([
            'order_id' => $event->order->id,
            'reason' => $event->reason
        ]);
    }
}

用户行为追踪

class UserActivityLogged
{
    public $user;
    public $action;
    public $metadata;
    public function __construct(User $user, $action, $metadata = [])
    {
        $this->user = $user;
        $this->action = $action;
        $this->metadata = $metadata;
    }
}
// 监听器
class TrackUserBehavior
{
    public function handle(UserActivityLogged $event)
    {
        Analytics::track($event->user->id, $event->action, $event->metadata);
    }
}

权限和认证

class UserLoggedIn
{
    public $user;
    public $ip;
    public function __construct(User $user, $ip)
    {
        $this->user = $user;
        $this->ip = $ip;
    }
}
// 监听器
class UpdateLoginHistory
{
    public function handle(UserLoggedIn $event)
    {
        LoginHistory::create([
            'user_id' => $event->user->id,
            'ip' => $event->ip,
            'logged_in_at' => now()
        ]);
    }
}
class CheckForSuspiciousActivity
{
    public function handle(UserLoggedIn $event)
    {
        if ($this->isSuspiciousIP($event->ip)) {
            // 触发额外验证
            event(new RequireAdditionalVerification($event->user));
        }
    }
}

最佳实践建议

  1. 不要滥用:只在真正需要解耦时使用事件
  2. 合理划分:一个事件可以有多个监听器,但不要过多
  3. 错误处理:为监听器添加失败处理逻辑
  4. 性能考虑:耗时操作应实现 ShouldQueue 接口
  5. 文档记录:清晰记录事件和监听器的对应关系

选择事件的判断标准:

  • 多个地方需要响应同一操作
  • 需要保持代码解耦
  • 操作可能需要在不同时间或异步执行
  • 业务流程的纵向分割点

抱歉,评论功能暂时关闭!