我正在制作一个控制台应用程序,它使用 SwiftMail 扩展来发送。根据我们的政策,我有两台虚拟机,一台用作 SMTP 中继,另一台用作应用程序服务器。通过 telnet 手动发送邮件到中继工作正常。使用 SwiftMail 时,它坏了。
header 已返回,$failure
变量中没有返回任何条目用于 send()
getHeaders()->toString()
的响应
Message-ID: <1351104631.508838778dc03@swift.generated>
Date: Wed, 24 Oct 2012 14:50:31 -0400
Subject: [YourSite] Feedback
From: noreply@localhost.com
To: sixeightzero@localhost.com
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: quoted-printable
如果我回显 send()
,我得到 1
。
boot.php
$app->register(new Silex\Provider\SwiftmailerServiceProvider(), array(
'swiftmailer.options' => array(
'host' => 'ip.host.relay',
'port' => 25,
'encryption' => null,
'auth_mode' => null
),
));
app.php
$message = \Swift_Message::newInstance( )
->setSubject('[YourSite] Feedback')
->setFrom(array('noreply@localhost.com'))
->setTo(array('sixeightzero@localhost.com'))
->setBody("Message!");
$app['mailer']->send($message, $failures);
当我在应用服务器上运行 TCP 转储并运行脚本时,没有建立 SMTP 连接,也没有抛出任何错误。
有人遇到过这个吗?由于我们的应用程序要求,我不想使用 sendmail 或邮件,而是使用 SMTP。
最佳答案
这是因为 SwiftmailerServiceProvider
默认使用 Swift_MemorySpool
,并且仅在 kernel.terminate
时刷新它。让我退后一步,解释其中的每一部分。
SwiftmailerServiceProvider
负责注册 Swiftmailer 服务和默认配置。默认情况下,传输 (swiftmailer.spooltransport
) 是Swift_SpoolTransport
而swiftmailer.spool
是Swift_MemorySpool
。Swiftmailer 支持不同的邮件发送方式。这些被称为传输。假脱机传输充当队列。您可以将此队列存储在文件或内存中。假脱机传输有一个
flushQueue
方法,它允许将排队的邮件刷新到一个真正的传输中,该传输应该传递它们。Silex 使用的 Symfony2 HttpKernel 在每个请求的生命周期中发出许多事件。它发出的最后一个是
kernel.terminate
事件。发送 HTTP 响应正文后触发此事件。这允许您在呈现页面后执行繁重的任务,以便它不再对用户显示为正在加载。SwiftmailerServiceProvider
订阅了kernel.terminate
事件,以便在页面呈现后刷新内存假脱机。它将它刷新到swiftmailer.transport
服务,这是一个Swift_Transport_EsmtpTransport
,它通过 SMTP 进行实际发送。
那么让我们来看看实际的问题。您处于 CLI 上下文中,因此不会触发任何 HttpKernel 事件。由于未触发 kernel.terminate
事件,因此不会刷新您的假脱机。因此您的电子邮件未发送。
有两个很好的解决方案:
A) 手动冲洗阀芯。只需执行提供者在其监听器中执行的操作即可。在您的 CLI 命令末尾添加:
if ($app['mailer.initialized']) { $app['swiftmailer.spooltransport']->getSpool()->flushQueue($app['swiftmailer.transport']); }
B) 重新配置
mailer
服务以直接使用 ESMTP 传输而不通过假脱机:$app['mailer'] = $app->share(function ($app) { return new \Swift_Mailer($app['swiftmailer.transport']); });
这两种解决方案都可以。祝你好运!
关于php - Silex SwiftMailer 在执行时不建立 SMTP 连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13055907/