You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel 12监听MessageSent事件返回空事件的问题排查

Laravel 12升级后MessageSent事件监听器无法获取邮件信息问题

从Laravel 8升级到Laravel 12后,原本用于记录邮件收件人、发送时间及主题的监听器失效,触发的MessageSent事件内容为空,无法读取邮件相关数据。

原Laravel 8中正常运行的日志代码:

Log::channel('mail')->info(now()->format('H:i:s d.m.Y') . ',  Email: ' . $event->message->getSubject() . ' an ' . implode(',', array_keys($event->message->getTo())) . ' wurde gesendet.');

问题根源确实与Laravel迁移至Symfony Mailer有关,Laravel 9及以后版本对邮件事件的属性结构做了调整。


相关代码参考

邮件发送代码

Mail::html($this->generateHtmlEmail($content, $user), static function ($msg) use ($user, $mail) {
    $msg->to($user->mail);
    $msg->subject($mail->title);
});

当前监听器代码(含调试语句)

<?php

namespace App\Listeners;

use Illuminate\Mail\Events\MessageSent;
use Illuminate\Mail\SentMessage;
use Illuminate\Support\Facades\Log;

class EmailSentListener
{
    public function __construct()
    {
        //
    }

    public function handle($event): void
    {
        /** @var SentMessage $message */
        $message = $event->sent;
        Log::channel('mail')->info(now()->format('H:i:s d.m.Y') . ',  Email: ' . $event->message->getSubject() . ' an ' . implode(',', array_keys($event->message->getTo())) . ' wurde gesendet.');
        Log::channel('mail')->info(json_encode($message));
    }
}

监听器注册代码

<?php

namespace App\Providers;

use App\Listeners\EmailSentListener;
use Illuminate\Auth\Events\Registered;
use Illuminate\Auth\Listeners\SendEmailVerificationNotification;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
use Illuminate\Mail\Events\MessageSent;

class EventServiceProvider extends ServiceProvider
{
    protected $listen = [
        Registered::class => [
            SendEmailVerificationNotification::class,
        ],
        MessageSent::class => [
            EmailSentListener::class,
        ],
    ];

    public function boot()
    {
        //
    }
}

修复方法

Laravel 9+ 切换到Symfony Mailer后,MessageSent事件的message属性不再直接指向Symfony邮件对象,需要通过sent属性获取SentMessage实例,再调用getOriginalMessage()方法获取真实的Symfony邮件对象:

修正后的监听器handle方法:

public function handle(MessageSent $event): void
{
    // 获取Symfony原生邮件对象
    $symfonyMessage = $event->sent->getOriginalMessage();
    
    $subject = $symfonyMessage->getSubject();
    $recipients = implode(',', array_keys($symfonyMessage->getTo()));
    
    Log::channel('mail')->info(
        now()->format('H:i:s d.m.Y') . ",  Email: {$subject} an {$recipients} wurde gesendet."
    );
}

同时建议为handle方法的参数添加类型声明MessageSent $event,提升代码可读性和类型安全。


内容的提问来源于stack exchange,提问作者Dusto

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 00:43:14