Mail数据库动态配置
版本laravel10
因为Mail是一个单例 这样的话在队列中/octane模式下不好去检查被配置是否已被更改
<?php
namespace Illuminate\Mail;
use Illuminate\Contracts\Support\DeferrableProvider;
use Illuminate\Support\ServiceProvider;
class MailServiceProvider extends ServiceProvider implements DeferrableProvider
{
/**
* Register the service provider.
*
* @return void
*/
public function register()
{
$this->registerIlluminateMailer();
$this->registerMarkdownRenderer();
}
/**
* Register the Illuminate mailer instance.
*
* @return void
*/
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();
});
}
}
所以在AppServiceProvider的boot方法中去覆盖单例注册 改成范围单例
$this->app->scoped('mail.manager', fn($app) => new MailManager($app));
然后每次解析Mail触发会回调 这里的驱动应该固定是smtp
Mail::resolved(function (MailManager $mail) {
$driver = system_config()->mailMailer();
$config = config("mail.mailers.$driver");
$config['host'] = system_config()->mailHost();
$config['port'] = system_config()->mailPort();
$config['username'] = system_config()->mailUsername();
$config['password'] = system_config()->mailPassword();
$config['encryption'] = system_config()->mailEncryption();
config()->set('mail.from.address', system_config()->mailFromAddress());
config()->set('mail.from.name', system_config()->mailFromName());
config()->set("mail.mailers.$driver", $config);
$mail->setDefaultDriver($driver);
});
如果存在问题请大佬们帮忙指出
高认可度评论:
好像在octane模式下可以不用管mail 它没有在预热数组里面 下次请求不会是同一个实例 因为在octane里面每次请求都是clone一个app容器实例 就算它是单例 下次请求也会重新实例化 但是改成范围单例也没关系 也不会有影响
让队列里面每次任务执行前都清除一下这个范围单例 保证每个任务都可以拿最新的配置 虽然也可以不用改成范围单例 也可以在looping事件里面去clear一下 facade类中静态数组里面的这个实例和容器数组里面的那个实例就可以了 facade类里面的感觉也可以不用清除 在队列中每次执行任务前会执行scope闭包 里面会把facade中的数组重置为空数组 只要手动清除一下容器里面的实例就可以了
这两种方式都可以
队列内和octane无关吧。。都是新创建的实例
好像在octane模式下可以不用管mail 它没有在预热数组里面 下次请求不会是同一个实例 因为在octane里面每次请求都是clone一个app容器实例 就算它是单例 下次请求也会重新实例化 但是改成范围单例也没关系 也不会有影响
让队列里面每次任务执行前都清除一下这个范围单例 保证每个任务都可以拿最新的配置 虽然也可以不用改成范围单例 也可以在looping事件里面去clear一下 facade类中静态数组里面的这个实例和容器数组里面的那个实例就可以了 facade类里面的感觉也可以不用清除 在队列中每次执行任务前会执行scope闭包 里面会把facade中的数组重置为空数组 只要手动清除一下容器里面的实例就可以了
这两种方式都可以