在Laravel中存在各种指南,但是我发现的所有(this和this)的所有指南只能完成Laravel 8的工作。原因是,在V9中,不再支持Swift Mailer支持Symfony Mailer。 Laravel文档显示了如何编写自己的自定义运输,但这不是我们在这里需要的。阅读此帖子时,可能会有一个软件包发送带有自定义SMTP参数的电子邮件,因此您可能需要先看一下。
Laravel在幕后做什么
我们要处理的第一件事与称为MailManager
的类有关。它负责配置和解决各种运输驱动程序。我们已经知道我们要使用SMTP传输,我们只需要知道如何覆盖来自.env
文件的默认配置即可。该MailManager
有一种方法:
protected function getConfig(string $name)
{
return $this->app['config']['mail.driver']
? $this->app['config']['mail']
: $this->app['config']["mail.mailers.{$name}"];
}
这是我们要覆盖的方法。在这样做之前,我们需要知道框架如何解决和使用MailManager
。在框架的MailServiceProvider
中,我们找到了这件代码:
protected function registerIlluminateMailer()
{
$this->app->singleton('mail.manager', function ($app) {
return new MailManager($app);
});
$this->app->bind('mailer', function ($app) {
return $app->make('mail.manager')->mailer();
});
}
这告诉我们,要使用另一个邮件而不是默认邮件,我们必须使用MailManager
的另一个实例并从中获取邮件。
实施自定义邮件
因此,我们将这个名为App\Extensions\UserMailManager
的新类称为“ App\Extensions\UserMailManager
”,将其放置或称其为您想要的任何东西,在创建并覆盖我们之前看到的getConfig()
方法时接受配置。
namespace App\Extensions;
use Illuminate\Mail\MailManager;
class UserMailManager extends MailManager
{
public function __construct($app, private readonly array $customConfig)
{
parent::__construct($app);
}
protected function getConfig(string $name)
{
return $this->customConfig;
}
}
在您的AppServiceProvider
或任何其他提供商中,我们将此新的MailManager
的实例绑定到容器,这将使我们在需要时传递自定义SMTP参数。可能是一个单身人士,不确定。
class AppServiceProvider extends ServiceProvider
{
public function register(): void
{
$this->app->bind('user.mailer', function ($app, $parameters) {
return (new UserMailManager($app, $parameters))->mailer();
});
}
...
}
到目前为止,您将使用我们的设置:
/** @var Mailer $mailer */
$mailer = app('user.mailer', $smtpParams);
$mailer->send($mailable);
这看起来并不那么方便。通常,您在users
表中的列中有SMTP参数(或其他表,都没关系)。我们将通过在User
模型中创建助手方法来利用它。
public function sendMail(Mailable $mailable)
{
if ($this->smtp_enabled) {
$smtpParams = [
'transport' => 'smtp',
'host' => $this->smtp_params['smtp_host'] ?? null,
'port' => $this->smtp_params['smtp_port'] ?? null,
'username' => $this->smtp_params['smtp_user'] ?? null,
'password' => $this->smtp_params['smtp_password'] ?? null,
'timeout' => null,
'verify_peer' => false,
];
/** @var Mailer $mailer */
$mailer = app('creator.mailer', $smtpParams);
$mailer->send($mailable);
} else {
Mail::send($mailable);
}
}
将邮件与自定义SMTP参数一起使用
现在,在要使用自定义参数的代码的其他部分中,您可以将Mail::send(new TestMail($testVariable))
与$user->sendMail(new TestMail($testVariable))
交换。方便,对吗?
如果您想排队邮件,我建议您添加一种名为queueMail($mailable, ...)
的新方法,并根据您的需求进行调整。唯一的区别可能是在方法内使用$mailer->queue($mailable);
。
就是这样。如果这对您有所帮助,请留下大拇指,并感谢您这么远。