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);
        });

如果存在问题请大佬们帮忙指出

《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 3

好像在octane模式下可以不用管mail 它没有在预热数组里面 下次请求不会是同一个实例 因为在octane里面每次请求都是clone一个app容器实例 就算它是单例 下次请求也会重新实例化 但是改成范围单例也没关系 也不会有影响
让队列里面每次任务执行前都清除一下这个范围单例 保证每个任务都可以拿最新的配置 虽然也可以不用改成范围单例 也可以在looping事件里面去clear一下 facade类中静态数组里面的这个实例和容器数组里面的那个实例就可以了 facade类里面的感觉也可以不用清除 在队列中每次执行任务前会执行scope闭包 里面会把facade中的数组重置为空数组 只要手动清除一下容器里面的实例就可以了

这两种方式都可以

1个月前 评论

队列内和octane无关吧。。都是新创建的实例

1个月前 评论
cccdz (楼主) 1个月前

好像在octane模式下可以不用管mail 它没有在预热数组里面 下次请求不会是同一个实例 因为在octane里面每次请求都是clone一个app容器实例 就算它是单例 下次请求也会重新实例化 但是改成范围单例也没关系 也不会有影响
让队列里面每次任务执行前都清除一下这个范围单例 保证每个任务都可以拿最新的配置 虽然也可以不用改成范围单例 也可以在looping事件里面去clear一下 facade类中静态数组里面的这个实例和容器数组里面的那个实例就可以了 facade类里面的感觉也可以不用清除 在队列中每次执行任务前会执行scope闭包 里面会把facade中的数组重置为空数组 只要手动清除一下容器里面的实例就可以了

这两种方式都可以

1个月前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!