Php Silex SwiftMailer在执行时未建立SMTP连接

Php Silex SwiftMailer在执行时未建立SMTP连接,php,swiftmailer,silex,Php,Swiftmailer,Silex,我正在制作一个控制台应用程序,它使用SwiftMail扩展发送。由于我们的政策,我有两个虚拟机,一个用作SMTP中继,另一个用作应用程序服务器。通过telnet手动向中继发送邮件效果良好。当使用快捷邮件时,它是坏的 返回标题,并且在send()的$failure变量中没有返回任何条目 响应getHeaders()->toString() app.php $app->register(new Silex\Provider\SwiftmailerServiceProvider(), array

我正在制作一个控制台应用程序,它使用SwiftMail扩展发送。由于我们的政策,我有两个虚拟机,一个用作SMTP中继,另一个用作应用程序服务器。通过telnet手动向中继发送邮件效果良好。当使用快捷邮件时,它是坏的

返回标题,并且在
send()的
$failure
变量中没有返回任何条目

响应
getHeaders()->toString()

app.php

$app->register(new Silex\Provider\SwiftmailerServiceProvider(), array(
    'swiftmailer.options' => array(
        'host' => 'ip.host.relay',
        'port' => 25,
        'encryption' => null,
        'auth_mode' => null
    ),
));
 $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或mail,但由于我们的应用程序要求,我想使用SMTP。

这是因为默认情况下,
SwiftmailerServiceProvider
使用
Swift\u MemorySpool
,并且只在
内核上刷新它。终止
。让我退一步,解释一下其中的每一部分

  • SwiftmailerServiceProvider
    负责注册Swiftmailer服务和默认配置。默认情况下,传输(
    swiftmailer.spooltransport
    )为
    Swift\u spooltransport
    swiftmailer.spool
    Swift\u MemorySpool

  • Swiftmailer支持不同的邮件发送方式。这些被称为运输工具。spool传输充当队列。您可以将此队列存储在文件或内存中。Spool传输有一个
    flushQueue
    方法,该方法允许将排队的邮件刷新到一个真正的传输,而真正的传输应该能够传递它们

  • Silex使用的Symfony2 HttpKernel在每个请求的生命周期中都会发出大量事件。它发出的最后一个事件是
    内核.terminate
    事件。此事件在发送HTTP响应正文后触发。这允许您在呈现页面后执行繁重的任务,以便不再显示为用户正在加载

  • SwiftmailerServiceProvider
    订阅
    内核。终止
    事件,以便在呈现页面后刷新内存假脱机。它将其刷新到
    swiftmailer.transport
    服务,这是一个
    Swift\u transport\u esmtp transport
    ,通过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']);
    });
    

这两种解决方案都可以。祝你好运

您是否尝试使用其他设备连接到发送服务器以确保其正在运行/侦听?是的,我从应用程序服务器远程登录到中继,并成功模拟收到的消息。在应用服务器上运行
app.php
时,我看不到任何出站SMTP通信,在relayPerfect上也没有入站SMTP,这是我自己想到的,但效果很好。使用选项
B
。谢谢@igorw!
$app['mailer'] = $app->share(function ($app) {
    return new \Swift_Mailer($app['swiftmailer.transport']);
});