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
相关产品推荐
相关产品推荐

