Silex SwiftMailer не выполняет подключение SMTP после выполнения

Я делаю консольное приложение, которое использует расширение SwiftMail для отправки. Из-за нашей политики у меня есть две виртуальные машины, одна из которых служит ретранслятором SMTP, а другая – сервером приложений. Отправка почты вручную через telnet на реле работает нормально. При использовании SwiftMail он сломан.

Заголовки возвращаются и нет записей, возвращаемых в переменной $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 из-за требований наших приложений.

Related of "Silex SwiftMailer не выполняет подключение SMTP после выполнения"

Это связано с тем, что SwiftmailerServiceProvider по умолчанию использует Swift_MemorySpool и только сбрасывает его на kernel.terminate . Позвольте мне сделать шаг назад и объяснить каждую часть этого.

  • SwiftmailerServiceProvider отвечает за регистрацию служб Swiftmailer и конфигурации по умолчанию. По умолчанию транспорт ( swiftmailer.spooltransport ) – Swift_SpoolTransport а swiftmailer.spoolSwift_MemorySpool .

  • Swiftmailer поддерживает различные способы отправки писем. Они называются транспортом. Транспортировка катушки действует как очередь. Вы можете сохранить эту очередь в файле или в памяти. Транспортировка катушек имеет метод flushQueue который позволяет сбрасывать почтовые отправления в реальный транспорт, который должен их доставлять.

  • Symfony2 HttpKernel, который использует Silex, испускает ряд событий в течение жизненного цикла каждого запроса. Последним, который он испускает, является событие kernel.terminate . Это событие запускается после отправки тела ответа HTTP. Это позволяет выполнять тяжелые задачи после рендеринга страницы, чтобы она больше не отображалась как загрузка пользователю.

  • SwiftmailerServiceProvider подписывается на событие kernel.terminate , чтобы очистить 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']); }); 

Любое решение должно делать. Удачи!