SwiftMailer 已废弃,Symfony 6.2 默认不兼容;Mailer 组件必须显式配置 transport,仅安装 symfony/mailer 不足,需在 mailer.yaml 中声明 transport(如 smtp://localhost:1025),Gmail DSN 必须含 ?auth_mode=login,模板路径以 templates/ 开头且变量用 context() 传递,spool 已移除,异步需完整配置 transport 和 worker。

SwiftMailer 已废弃,Symfony 6.2 默认不兼容它。你装了 symfony/swiftmailer-bundle 或手动引入 swiftmailer/swiftmailer,邮件也不会走通——组件被彻底移除,调用会直接报错或静默 fallback 到 null://。
Mailer 组件必须显式配置 transport
只装 symfony/mailer 不够,MailerInterface::send() 会抛出 LogicException: No transport configured。这不是环境变量没读到,是 Symfony 故意设计成“零默认”:你得在 config/packages/mailer.yaml 里写死 transport 字段。
- 开发时最稳写法:
transport: 'smtp://localhost:1025'(配 MailHog)或transport: 'sendmail://default' - 别留空、别写
transport: null、别依赖MAILER_DSN环境变量自动 fallback——它可能被忽略 - 运行
bin/console debug:config mailer,确认输出里transports下的 DSN 和你预期一致,不是null://
Gmail DSN 必须带 ?auth_mode=login
用 Gmail 发信,MAILER_DSN=gmail://... 或 smtp://... 都行,但漏掉 ?auth_mode=login 就连不上——Gmail 拒绝认证,且不报错,邮件静默消失。
- 正确示例:
MAILER_DSN=gmail://you@gmail.com:your_app_password@default?auth_mode=login - 错误组合:
smtps://...(已废弃)、smtp://...?encryption=tls(缺auth_mode=login)、smtp://...&username=...(重复参数导致解析失败) - 应用密码不是账户密码,得在 Google 账户里开“两步验证”后生成 16 位密钥
模板路径和传参必须严格按规则
用 TemplatedEmail 渲染 HTML 邮件时,路径和变量传递错一个字符,模板就 404 或变量为空。
- 模板路径必须以
templates/开头,调用时只写相对路径:htmlTemplate('email/welcome.html.twig')(不是templates/email/welcome.html.twig) - 变量必须用
->context(['user' => $user]),不是->with()(那是SwiftMailer的旧写法) - 如果开了
inline_css: true却没装symfony/css-selector和tijsverkoyen/css-to-inline-styles,Mailer 自动降级为纯文本,无提示
异步和 spool 是静默失败的重灾区
Symfony 6.2+ 已移除 spool,但如果你的配置里还残留 spool: { type: memory },Mailer 会悄悄 fallback 到 null://;而一旦项目启用了 messenger-bundle,邮件默认进队列,不跑 php bin/console messenger:consume 就卡住不动。
- 开发阶段建议删掉所有
spool:配置项 - 禁用异步:在
config/packages/mailer.yaml显式写transport: 'smtp',别用async:// - 真要异步,得配
enqueue或amqptransport,并启动 worker,不是光改 DSN 就行
context()、异步机制关干净——少一个,它就不响,也不报错,只丢信。


















