Laravel-快速更改电子邮件设置不起作用

时间:2019-03-30 06:06:49

标签: php email laravel-5.8

我对应用程序的所有电子邮件设置都存储在数据库中。用户可以选择更改这些设置,并且一切正常。但是我正在尝试设置“发送测试电子邮件”功能,以允许用户在保存之前测试其设置。当他们提交用于发送测试电子邮件的表单时,将通过原始设置而非新设置发送电子邮件。

该表单已提交到SettingsController.php

//  Send a test email
public function sendTestEmail(Request $request)
{
   Log::info(config('mail.host'));  
   //  Just to check the current email host - shows the proper host 
   //  from the database - i.e. smtp.mailtrap.io

   //  Make sure that all of the information properly validates
   $request->validate([
       'host'       => 'required',
       'port'       => 'required|numeric',
       'encryption' => 'required',
       'username'   => 'required'
   ]);

   //  Temporarily set the email settings
   config([
       'mail.host'       => $request->host,
       'mail.port'       => $request->port,
       'mail.encryption' => $request->encryption,
       'mail.username'   => $request->username,
   ]);
   //  Only update the password if it has been changed
   if(!empty($request->password))
   {
       config(['mail.password' => $request->password]);
   }

   //  Try and send the test email
   try
   {
       Log::info(config('mail.host'));
       //  Just to check the new setting - this also shows the correct
       //  email host - which is the newly assigned one via the form 
       //  i.e. smtp.google.com

       Mail::to(Auth::user()->email)->send(new TestEmail());
       return response()->json([
           'success' => true,
           'sentTo'  => Auth::user()->email
       ]);
   }
   catch(Exception $e)
   {
       Log::notice('Test Email Failed.  Message: '.$e);
       $msg = '['.$e->getCode().'] "'.$e->getMessage().'" on line '.
            $e->getTrace()[0]['line'].' of file '.$e->getTrace()[0]['file'];
       return response()->json(['message' => $msg]);
   }
}

在我的TestEmail类中,我已将其归结为基本内容

namespace App\Mail;

//use Illuminate\Bus\Queueable;  //  Commented out to be sure it is not queuing
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
//use Illuminate\Contracts\Queue\ShouldQueue;  //  Commented out to be sure it is not queuing

class TestEmail extends Mailable
{
//    use Queueable, SerializesModels;  //  Commented out to be sure it is not queuing

 /**
 * Create a new message instance.
 *
 * @return void
 */
public function __construct()
{
    //
}

/**
 * Build the message.
 *
 * @return $this
 */
public function build()
{
    return $this->subject('Test Email From '.config('app.name'))->markdown('email.testEmail');
}
}

即使日志显示了配置设置的更新的smtp主机,消息仍通过原始设置发送,即smtp.mailtrap.io。

3 个答案:

答案 0 :(得分:2)

TL; DR

您的问题的立即答案,请参考以下在 Laravel 5.8 上测试的代码:

$transport = app('swift.transport');
$smtp = $transport->driver('smpt');
$smpt->setHost('PUT_YOUR_HOST_HERE');
$smpt->setPort('THE_PORT_HERE');
$smpt->setUsername('YOUR_USERNAME_HERE');
$smpt->setPassword('YOUR_PASSWORD_HERE');
$smpt->setEncryption('YOUR_ENCRYPTION_HERE');

为什么不能即时设置配置?

在laravel架构中,首先要注册所有服务提供商,其中包括MailServiceProvider。查看您的 config / app.php

    // inside config/app.php
    ...
    Illuminate\Mail\MailServiceProvider::class,
    ...

配置将在到达您的路由之前加载,请参见 Illuminate \ Mail \ TransportManager

    /**
     * Create an instance of the SMTP Swift Transport driver.
     *
     * @return \Swift_SmtpTransport
     */
    protected function createSmtpDriver()
    {
        $config = $this->app->make('config')->get('mail');

        // The Swift SMTP transport instance will allow us to use any SMTP backend
        // for delivering mail such as Sendgrid, Amazon SES, or a custom server
        // a developer has available. We will just pass this configured host.
        $transport = new SmtpTransport($config['host'], $config['port']);

        if (isset($config['encryption'])) {
            $transport->setEncryption($config['encryption']);
        }
        //... rest of the code
   }

因此,我使用TransportManager的drivers方法处理此问题的方式来选择所需的驱动程序并设置所需的配置,因为上面的代码我们可以看到其api的大量用法。

希望这会有所帮助

答案 1 :(得分:0)

您可以使用Config :: set:

即时设置/更改任何配置。

Config::set('key', 'value'); 因此,要设置/更改mail.php中的端口,您可以尝试以下操作:

Config::set('mail.port', 587); // default
  
    
      

注意:在运行时设置的配置值仅针对当前请求设置,不会结转到后续请求

    
  

答案 2 :(得分:0)

我面临同样的问题,我只是使用

config(['mail.driver' => 'smtp']);

当我调试时

dd(config('mail.driver'));

配置没问题

我刚刚查看了 kfirba 的评论 here

<块引用>

我很确定这个问题是因为当 Laravel 在 IoC 容器中注册邮件程序密钥时它使用原始配置。更改它不会导致 laravel 重新定义邮件程序键。 如果您查看 MailerServiceProvider,您会看到它是延迟的,这意味着一旦您调用它,它将实例化对象并使用单例。我相信您已经在应用程序的其他地方使用了 Mail::send() 方法,这导致在应用程序中注册邮件程序密钥。由于它是单例,因此当您重新使用它时,它不会再次读取您的配置文件。

解决方案:

config(['mail.driver' => 'smtp']);
(new Illuminate\Mail\MailServiceProvider(app()))->register();

适用于 Laravel 8