Laravel 6.2 队列发送Notification时动态切换邮件服务器不生效求助
问题解决方法
核心原因
Laravel 服务容器会在首次调用邮件服务时实例化Mailer对象并缓存,队列worker属于常驻进程,启动阶段就完成了基础服务初始化,后续通过Config::set修改的配置无法触发已经实例化的Mailer重新加载,所以实际发件仍然使用启动时的默认配置。
方案1:预设多套邮件配置(推荐)
适合邮件服务器固定的场景,提前在配置文件中声明所有需要用到的邮件服务器:
- 首先编辑
config/mail.php,在mailers数组下新增自定义配置:
'mailers' => [ 'default' => [ // 原有默认配置 ], 'notification_server' => [ 'transport' => 'smtp', 'host' => '你的通知服务器地址', 'port' => 端口号, 'username' => '账号', 'password' => '密码', 'encryption' => 'tls', 'from' => [ 'address' => '发件人地址', 'name' => '发件人名称', ], ], // 其他需要的邮件服务器配置 ],
- 然后在Notification类的
toMail方法中,按业务条件指定对应邮件驱动器即可:
public function toMail($notifiable) { // 按你的业务逻辑判断需要使用的邮件服务器 $useMailer = 条件判断 ? 'notification_server' : 'default'; return (new MailMessage) ->mailer($useMailer) ->subject('通知标题') ->line('通知内容正文'); }
方案2:动态创建自定义Mailer实例
适合邮件配置存储在数据库、需要动态拉取的场景:
use Illuminate\Support\Facades\Mail; // 动态获取你的邮件配置(比如从数据库读取) $customConfig = [ 'transport' => 'smtp', 'host' => $动态host, 'port' => $动态端口, 'username' => $动态账号, 'password' => $动态密码, 'encryption' => $加密方式, 'from' => [ 'address' => $发件人地址, 'name' => $发件人名称, ], ]; // 创建临时自定义Mailer实例,不会复用全局缓存的实例 // Laravel 9及以上版本写法 $customMailer = Mail::manager()->mailer('custom', $customConfig); // 发送通知时指定使用自定义Mailer $notifiable->notify((new 你的通知类())->mailer($customMailer));
队列适配注意事项
如果使用异步队列,务必将邮件服务器的判断逻辑写在Notification类的toMail方法内,不要写在任务分发的逻辑中,避免分发时的上下文到队列执行时过期导致判断错误。
内容的提问来源于stack exchange,提问作者jbe49
相关产品推荐
相关产品推荐

