You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Symfony Mailer发送邮件后获取所使用的传输方式?

如何获取Symfony Mailer中Failover传输实际使用的子传输

当你用Symfony Mailer的Failover传输时,默认的SentMessageEvent里没法直接拿到实际生效的子传输,试试下面这两种方法:

方法1:通过事件监听器获取Failover的最后使用传输

Symfony的FailoverTransport类自带getLastUsedTransport()方法,能直接拿到最后成功发送邮件的子传输。写个事件监听器就能搞定:

先创建监听器类:

use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Mailer\Event\SentMessageEvent;
use Symfony\Component\Mailer\Transport\FailoverTransport;

class MailTransportLogger implements EventSubscriberInterface
{
    public static function getSubscribedEvents(): array
    {
        return [
            SentMessageEvent::class => 'logTransport',
        ];
    }

    public function logTransport(SentMessageEvent $event): void
    {
        $transport = $event->getTransport();
        
        if ($transport instanceof FailoverTransport) {
            $actualTransport = $transport->getLastUsedTransport();
            // 这里可以把传输信息存日志或者做其他处理
            // 比如拿类名:$actualTransport::class
            // 如果需要DSN,要是传输实现了DsnAwareInterface,还能调用getDsn()
            error_log("Failover实际用了: " . $actualTransport::class);
        } else {
            // 非Failover传输直接拿信息
            error_log("用了传输: " . $transport::class);
        }
    }
}

然后在services.yaml里注册这个监听器:

services:
    App\EventSubscriber\MailTransportLogger:
        tags:
            - { name: kernel.event_subscriber }

方法2:自定义Failover传输,给消息加标记

要是你想把实际传输信息直接加到邮件头里,可以自定义一个Failover传输的子类:

use Symfony\Component\Mailer\Transport\FailoverTransport;
use Symfony\Component\Mailer\SentMessage;
use Symfony\Component\Mime\RawMessage;
use Symfony\Component\Mailer\Envelope;

class TrackableFailoverTransport extends FailoverTransport
{
    public function send(RawMessage $message, Envelope $envelope = null): SentMessage
    {
        $sentMessage = parent::send($message, $envelope);
        
        $actualTransport = $this->getLastUsedTransport();
        // 给原始消息加个自定义头,后续就能从消息里拿到
        $sentMessage->getOriginalMessage()->getHeaders()->addTextHeader('X-Used-Transport', $actualTransport::class);
        
        return $sentMessage;
    }
}

之后需要替换Symfony默认的FailoverTransport,这一步需要自定义传输工厂,适合需要在邮件里直接带上传输信息的场景。

注意点

  • 只有当传输是FailoverTransport实例时,才能调用getLastUsedTransport(),所以记得先做类型判断。
  • 只要你的Failover DSN是用failover(...)格式定义的,Symfony就会自动用FailoverTransport,上面的方法都适用。
  • 普通传输直接从SentMessageEvent的getTransport()就能拿到对应对象,获取类名或者DSN都没问题。

内容的提问来源于stack exchange,提问作者OVG

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 06:45:05