Laravel通知:via方法赋值变量在toMail方法中始终为null
问题原因及解决办法
核心原因
你的$code在toMail中返回null,本质是队列通知的序列化机制与方法执行顺序不匹配导致的,具体分以下几种情况:
1. 队列中存在旧的未处理任务
修改代码前生成的队列任务还未被处理时,这些任务的通知实例在序列化时$code还未被赋值(当时的代码里via方法还没有设置$code),worker处理这些旧任务时自然返回null。
2. via方法的设计用途不适合赋值属性
Laravel的via方法仅用于确定通知渠道,虽然你在其中赋值了$code,但在队列场景下:
- 分发通知时会先调用
via确定渠道,然后序列化通知实例存入队列; - 若序列化过程中因
SerializesModelstrait或自定义逻辑丢失了$code的值(比如GlobalMailHelperTrait覆盖了序列化方法但未包含$code),反序列化后$code就会变为null。
3. 自定义Trait干扰了序列化
如果你的GlobalMailHelperTrait中定义了__serialize或__unserialize方法,且没有将$code纳入序列化范围,就会导致这个变量的值在序列化时被丢弃。
解决办法
方法1:清理旧队列任务并重启Worker
停止当前运行的队列Worker,清理旧任务,再重启Worker以加载新代码:
# 停止Worker(后台运行需找到进程杀死) php artisan queue:clear # 清除所有未处理的旧任务 php artisan queue:work # 重启Worker
方法2:在构造函数中赋值属性(推荐)
将$code的赋值逻辑移到构造函数中,这样在序列化时变量值会被正常保存:
class FinancialQuestionnaireSubmissionNotification extends Notification implements ShouldQueue { use Queueable,SerializesModels, GlobalMailHelperTrait; public Lead $lead; public $code; public function __construct(Lead $lead) { $this->lead = $lead->fresh(); $this->code = 'xyz'; // 直接在构造函数赋值 } public function via($notifiable) { return ['mail']; } public function toMail($notifiable) { dd($this->code); // 现在会输出'xyz' } }
方法3:检查并修复序列化逻辑
如果GlobalMailHelperTrait自定义了序列化方法,确保将$code加入序列化数组:
// 在GlobalMailHelperTrait中修改序列化方法 public function __serialize(): array { // 先调用父类的序列化逻辑(比如SerializesModels的) $serialized = parent::__serialize(); // 加入$code变量 $serialized['code'] = $this->code; return $serialized; }
内容的提问来源于stack exchange,提问作者Jigar
相关产品推荐
相关产品推荐

