symfony/mailerでメールが送信されない問題

結論から言うと、messenger.yamlで[Symfony\Component\Mailer\Messenger\SendEmailMessage]を外すように設定するか、mailer.yamlでmessege_busをfalseに設定する。もしくはmessenger:consumeコマンドを実行することのいずれかで送信できます。

messenger.yamlでの場合

#config/packages/messenger.yaml
        routing:
            #これを除外する
            #Symfony\Component\Mailer\Messenger\SendEmailMessage: async
            Symfony\Component\Notifier\Message\ChatMessage: async
            Symfony\Component\Notifier\Message\SmsMessage: async

mailer.yamlでの場合

# config/packages/mailer.yaml
framework:
    mailer:
        message_bus: false #ここ

非同期で実行する場合

php bin/console messenger:consume async

上記コマンドを実行する場合、プロダクト環境で実行する場合は立ち上げっぱなしにするとメモリを大量消費するので、送信上限を設け定期的に実行するするなど注意が必要。

状況の再現

問題をGmailでの設定を例に挙げてみます。

.envを下記のように設定。APP_PASSWORDはgoogleアカウントから設定。方法はこちら

#USERNAMEは@gmail.comは不要
MAILER_DSN="gmail://USERNAME:APP_PASSWORD@default"

以下のようにコントローラーから呼び出しても、メールが送信されない。

//XXXController.php内での動作
 public function action(MailerInterface $mailer)
{
  $email = new Email();
  //...
  $mailer->send($email);
}

しかし以下のように直接Transportクラスから呼び出すと送信できる。

$transport = Transport::fromDsn('gmail://USERNAME:APP_PASS@default');
$mailer = new Mailer($transport);
$email = new Email();
//...
$mailer->send($email);

これはMessengerの機能で、メール送信の非同期に処理処理が有効になっている場合は送信処理がコード実行時はされない。デフォルトでこの非同期処理が有効になっていることがMailerのページで説明がないどころか、すぐに送信されると説明されてしまっているせいでソースを追っかけたり丸一日潰してしまった。