Laravel Mailable队列任务报错:Trying to get property 'email' of non-object 求助
解决Laravel队列邮件任务中"Trying to get property 'email' of non-object"错误
看起来你遇到的这个错误,核心原因是Laravel在处理邮件收件人时,无法正确识别你传递的字符串格式地址,尤其是在队列环境下的序列化/反序列化过程中。下面我会一步步分析问题并给出可行的解决方案:
可能的原因
- Laravel版本兼容性:如果你使用的是Laravel 5.8或更早版本,Mailable类处理字符串收件人的逻辑存在小问题——当你传递字符串地址时,内部会将其转为包含
address键的数组,再转成对象,但代码却尝试访问email属性,导致报错。 - 队列序列化限制:如果你的队列驱动使用了JSON序列化(比如Redis队列的JSON序列化器),
protected属性无法被正确序列化和反序列化,导致$this->email在队列执行时丢失或变成非预期值。 - 属性访问权限:虽然同一类中
protected属性可以访问,但在队列反序列化的特殊场景下,可能出现属性无法正常读取的情况。
解决方案
方案1:显式使用数组格式传递收件人
修改Mailable的build方法,将收件人以包含email键的数组形式传递,这样Laravel能正确识别属性:
public function build() { return $this ->from('test@test.com', env('TENANT_NAME')) ->replyTo(env('TENANT_EMAIL')) ->to(['email' => $this->email, 'name' => $this->username]) // 显式数组格式 ->subject('Test') ->view('api.emails.user-login-details') ->with([ 'username' => $this->username, 'password' => $this->password, ]); }
方案2:将属性改为public确保序列化正常
把Mailable中的protected属性改为public,这样无论哪种队列序列化方式,都能正确保存和恢复属性值:
class UserLoginDetailsMail extends Mailable { use Queueable, SerializesModels; public String $username; public String $email; public String $password; // 构造函数和其他代码保持不变 }
方案3:传递收件人时同时指定姓名(即使为空)
在调用to方法时,第二个参数传入姓名(空字符串也可以),让Laravel正确生成收件人结构:
->to($this->email, '')
方案4:升级Laravel版本(如果可行)
如果你的项目允许,升级到Laravel 6.x或更高版本,这些版本已经修复了旧版本中收件人处理的逻辑问题,字符串格式的收件人能被正确解析。
测试建议
先尝试用同步发送邮件的方式测试(Mail::send()代替Mail::queue()),如果同步发送正常,说明问题出在队列序列化上,方案2会更有效;如果同步发送也报错,那大概率是Laravel版本或收件人格式的问题,方案1或3能解决。
内容的提问来源于stack exchange,提问作者Ricky Barnett
相关产品推荐
相关产品推荐

