我对应用程序的所有电子邮件设置都存储在数据库中。用户可以选择更改这些设置,并且一切正常。但是我正在尝试设置“发送测试电子邮件”功能,以允许用户在保存之前测试其设置。当他们提交用于发送测试电子邮件的表单时,将通过原始设置而非新设置发送电子邮件。
该表单已提交到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。
答案 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'));
配置没问题
我很确定这个问题是因为当 Laravel 在 IoC 容器中注册邮件程序密钥时它使用原始配置。更改它不会导致 laravel 重新定义邮件程序键。 如果您查看 MailerServiceProvider,您会看到它是延迟的,这意味着一旦您调用它,它将实例化对象并使用单例。我相信您已经在应用程序的其他地方使用了 Mail::send() 方法,这导致在应用程序中注册邮件程序密钥。由于它是单例,因此当您重新使用它时,它不会再次读取您的配置文件。
config(['mail.driver' => 'smtp']);
(new Illuminate\Mail\MailServiceProvider(app()))->register();
适用于 Laravel 8