Laravel Mailable队列:如何向MessageSent事件传递自定义数据
在Laravel队列发送Mailable时给MessageSent事件传递自定义数据
嘿,这个场景我之前处理过,给你分享两种实用的方法,都能完美解决队列下发自定义数据到MessageSent事件的需求:
方法一:通过Mailable类的自定义属性传递(推荐)
这种方法最直接,因为MessageSent事件本身就会携带对应的Mailable实例,我们只需要在Mailable里定义好要传递的属性,发送时赋值就行:
在你的Mailable类中添加自定义属性
比如我有个OrderShippedMailable,新增一个public属性来存自定义数据:class OrderShipped extends Mailable { use Queueable, SerializesModels; // 自定义属性,用来存储要传递给事件的数据 public $customData; public function __construct() { // 构造函数逻辑不变 } public function build() { return $this->view('emails.orders.shipped'); } }发送Mailable时赋值自定义数据
不管是同步发送还是队列发送,都可以直接给属性赋值,或者用with方法:// 队列发送的示例 $mailable = new OrderShipped(); // 直接给public属性赋值 $mailable->customData = [ 'order_id' => 123, 'user_id' => 456, 'send_time' => now()->toDateTimeString() ]; Mail::to($user)->queue($mailable);在监听器中获取自定义数据
到LogSentEmailNotification监听器的handle方法里,通过$event->mailable拿到Mailable实例,再读取属性:public function handle(MessageSent $event) { // 先判断是不是我们目标的Mailable类型,避免处理其他邮件 if ($event->mailable instanceof OrderShipped) { $customData = $event->mailable->customData; // 这里就可以把数据写入日志或数据库了 \Illuminate\Support\Facades\Log::info('已发送邮件记录', $customData); } }
方法二:利用Swift_Message的自定义邮件头传递
如果不想修改Mailable类,或者数据是临时的,还可以给邮件本身加自定义头信息,在事件里读取:
在Mailable的build方法中添加自定义邮件头
用withSwiftMessage闭包给Swift_Message添加自定义头:public function build() { return $this->view('emails.orders.shipped') ->withSwiftMessage(function ($message) { // 把自定义数据转成JSON字符串存到自定义头里 $message->getHeaders()->addTextHeader( 'X-Email-Custom-Data', json_encode(['order_id' => 123, 'user_id' => 456]) ); }); }在监听器中读取自定义头数据
从$event->message(Swift_Message实例)中获取头信息,再解析成数组:public function handle(MessageSent $event) { $customHeader = $event->message->getHeaders()->get('X-Email-Custom-Data'); if ($customHeader) { $customData = json_decode($customHeader->getValue(), true); // 处理你的日志逻辑 } }
注意事项
- 用队列发送时,Mailable会被序列化,所以自定义属性要确保是可序列化的(比如不要包含资源型对象,模型的话用
SerializesModelstrait自动处理)。 - 第一种方法更直观,和业务逻辑绑定更紧密;第二种方法更灵活,适合临时加数据的场景。
内容的提问来源于stack exchange,提问作者cyberfly
相关产品推荐
相关产品推荐

