11

SwiftMail 拡張機能を使用して送信するコンソール アプリケーションを作成しています。私たちのポリシーにより、私は 2 つの仮想マシンを持っています。1 つは SMTP リレーとして機能し、もう 1 つはアプリケーション サーバーです。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 や mail は使用したくありませんが、アプリケーションの要件により SMTP を使用します。

4

1 に答える 1

41

これは、がデフォルトで を使用し、 でのみフラッシュするためSwiftmailerServiceProviderです。一歩下がって、これの各部分を説明しましょう。Swift_MemorySpoolkernel.terminate

  • SwiftmailerServiceProvider、Swiftmailer サービスとデフォルト構成の登録を担当します。デフォルトでは、トランスポート ( swiftmailer.spooltransport) はSwift_SpoolTransportであり、swiftmailer.spoolは ですSwift_MemorySpool

  • Swiftmailer は、メールを送信するさまざまな方法をサポートしています。これらはトランスポートと呼ばれます。スプール トランスポートはキューとして機能します。このキューは、ファイルまたはメモリに保存できます。スプール トランスポートにはflushQueue、キューに入れられたメールを実際のトランスポートにフラッシュできるメソッドがあります。

  • Silex が使用する Symfony2 HttpKernel は、すべてのリクエストのライフサイクル中に多数のイベントを発行します。それが発行する最後のものはkernel.terminateイベントです。このイベントは、HTTP 応答本文が送信された後にトリガーされます。これにより、ページをレンダリングした後に負荷の高いタスクを実行できるため、ユーザーにはロードしているように見えなくなります。

  • は、ページがレンダリングされた後にメモリ スプールをフラッシュするためにSwiftmailerServiceProvider、イベントをサブスクライブします。これは、 SMTP 経由で実際の送信を行うサービスkernel.terminateにフラッシュします。swiftmailer.transportSwift_Transport_EsmtpTransport

それでは、実際の問題に取り掛かりましょう。CLI コンテキストにいるため、これらの HttpKernel イベントは発生しません。イベントが発生しないためkernel.terminate、スプールはフラッシュされません。したがって、あなたのメールは送信されません。

これには 2 つの適切な解決策があります。

  • A) スプールを手動で洗い流します。プロバイダーがリスナーで行うことを行うだけです。これを CLI コマンドの最後に追加します。

    if ($app['mailer.initialized']) {
        $app['swiftmailer.spooltransport']->getSpool()->flushQueue($app['swiftmailer.transport']);
    }
    
  • mailerB)スプールを経由せずに ESMTP トランスポートを直接使用するようにサービスを再構成します。

    $app['mailer'] = $app->share(function ($app) {
        return new \Swift_Mailer($app['swiftmailer.transport']);
    });
    

どちらの解決策も必要です。幸運を!

于 2012-10-25T02:48:21.310 に答える