gpt4 book ai didi

laravel - 如何在 Laravel 5.4 中为排队电子邮件设置动态 SMTP 数据?

转载 作者:行者123 更新时间:2023-12-02 13:18:38 25 4
gpt4 key购买 nike

在我的应用程序中,每个用户都可以使用自己的 SMTP 服务器。因此必须提供配置。我正在使用 Laravel 通知来发送电子邮件。如果我不使用队列(这意味着同步),则没有问题。

我创建了一个 CustomNotific 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 配置。即使主管重新启动队列,也有可能同时发送多封具有不同配置的电子邮件。

最佳答案

在 Laravel 5.4+ 中,我看到 Mailer 类是一个包含 MailTransport 类的单例,它负责 SMTP 邮件的配置,也是一个单例;我只需使用以下方法覆盖配置:

首先,我设置了一个特征,这样我就可以在某些邮件上打开此功能:

trait MailSenderChangeable
{
/**
* @param array $settings
*/
public function changeMailSender($settings)
{
$mailTransport = app()->make('mailer')->getSwiftMailer()->getTransport();
if ($mailTransport instanceof \Swift_SmtpTransport) {
/** @var \Swift_SmtpTransport $mailTransport */
$mailTransport->setUsername($settings['email']);
$mailTransport->setPassword($settings['password']);
}
}
}

然后,在邮件类的 build() 方法中,您可以利用上述特征并调用:

    $this->changeMailSender([
'email'=>$this->company->email,
'password'=>$this->company->email_password,
]);

Boom,让 Laravel 完成剩下的工作。

关于laravel - 如何在 Laravel 5.4 中为排队电子邮件设置动态 SMTP 数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45327955/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com