【发布时间】:2018-01-01 20:02:58
【问题描述】:
在我的应用程序中,每个用户都可以使用自己的 SMTP 服务器。因此必须提供配置。我正在使用 Laravel 通知发送电子邮件。如果我不使用队列(这意味着同步),则没有问题。
我创建了一个 CustomNotifiable Trait:
config([
'mail.host' => $setting->smtp_host,
'mail.port' => $setting->smtp_port,
'mail.username' => $setting->smtp_username,
'mail.password' => $setting->smtp_password,
'mail.encryption' => $setting->smtp_encryption,
'mail.from.address' => $setting->smtp_from_address,
'mail.from.name' => $setting->smtp_from_name,
]);
(new \Illuminate\Mail\MailServiceProvider(app()))->register();
之后,我恢复原来的配置:
config([
'mail' => $originalMailConfig
]);
(new \Illuminate\Mail\MailServiceProvider(app()))->register();
到目前为止没问题。 但是,如果它已排队,即使提供了任何其他 SMTP 配置,也只会将启动队列工作程序后的第一个配置用于所有后续电子邮件。 config/mail.php 中的默认配置将被覆盖。但这只适用于第一次。
我在 AppServiceProvider::boot 方法中做了(SMTP 配置存储在通知中):
Queue::before(function (JobProcessing $event) {
// Handle queued notifications before they get executed
if (isset($event->job->payload()['data']['command']))
{
$payload = $event->job->payload();
$command = unserialize($payload['data']['command']);
// setting dynamic SMTP data if required
if (isset($command->notification->setting))
{
config([
'mail.host' => $command->notification->setting->smtp_host,
'mail.port' => $command->notification->setting->smtp_port,
'mail.username' => $command->notification->setting->smtp_username,
'mail.password' => $command->notification->setting->smtp_password,
'mail.encryption' => $command->notification->setting->smtp_encryption,
'mail.from.address' => $command->notification->setting->smtp_from_address,
'mail.from.name' => $command->notification->setting->smtp_from_name,
]);
(new \Illuminate\Mail\MailServiceProvider(app()))->register();
}
}
});
当然,原来的配置会恢复:
Queue::after(function (JobProcessed $event) use ($originalMailConfig) {
$payload = $event->job->payload();
$command = unserialize($payload['data']['command']);
// restore global mail settings
if (isset($command->notification->setting))
{
config([
'mail' => $originalMailConfig
]);
(new \Illuminate\Mail\MailServiceProvider(app()))->register();
}
});
看起来,Swift Mailer 有一个缓存或类似的东西。我注册了一个新的 MailServiceProvider,它应该只是替换旧的。因此,如果我使用新的 SMTP 数据设置配置,新注册的提供者应该接受它们。记录配置甚至在 TransportManager 中显示,在发送邮件之前设置了正确的 SMTP 数据,但邮件是使用第一个设置的配置发送的。
我找到了这个帖子并尝试了链接的解决方案,但结果相同:How to set dynamic SMTP details laravel
所以我需要一种方法来覆盖 Services / ServiceProvider / SMTP 配置。即使 Supervisor 重新启动队列,也有可能同时发送多封具有不同配置的电子邮件。
【问题讨论】:
标签: laravel swiftmailer