SMTP配置错字符或Twig模板路径不以templates/开头是Symfony邮件失败主因;MAILER_DSN格式须严格匹配服务商,如Gmail需?auth_mode=login和encryption=tls,模板路径必须为templates/xxx.html.twig且传参用context()。

SMTP 配置错一个字符,邮件就静默失败;模板路径不以 templates/ 开头,Twig 直接报 Unable to find template —— 这两个点是 90% 的 Symfony 邮件发送失败根源。
MAILER_DSN 格式必须严格匹配服务商要求
不是所有 SMTP 服务都用同一套参数。Gmail 必须带 ?auth_mode=login,否则即使账号密码正确也连不上;465 端口要配 encryption=ssl,587 端口则必须是 encryption=tls。写成 smtps:// 却不声明加密方式,Mailer 会直接 fallback 到 null://,不报错、不发信。
-
MAILER_DSN=smtp://user:pass@smtp.gmail.com:587?encryption=tls&auth_mode=login(Gmail 正确写法) -
MAILER_DSN=smtp://user:pass@smtp.sendgrid.net:587?encryption=tls(SendGrid 不需要auth_mode) -
MAILER_DSN=sendmail://default(本地开发最稳,免认证) - 别在
.env里写注释或空格,MAILER_DSN = "..."中的空格会导致解析失败
运行 bin/console debug:config mailer,确认输出里 transports 下真有你配的 DSN,而不是显示 null://。
TemplatedEmail 的模板路径和传参方式不能错
TemplatedEmail 不接受任何绝对路径或相对路径变体,只认 templates/xxx.html.twig 这种格式。传参也必须走 context(),不是 with() —— 后者在模板里取不到变量,且无提示。
- 模板文件必须放在
templates/email/welcome.html.twig,调用时写email/welcome.html.twig - 错误写法:
src/Resources/views/email/welcome.html.twig或/templates/email/welcome.html.twig - 正确传参:
->context(['user' => $user, 'token' => $token]) - 错误写法:
->with(['user' => $user])(变量在模板中为null) - 如果用了
inline_css: true,确保已安装symfony/css-selector和tijsverkoyen/css-to-inline-styles,否则自动降级为纯文本,不警告
别让 spool 或异步队列吞掉你的邮件
默认配置下,Mailer 是同步发送的。但如果你启用了 Messenger 异步传输(比如 framework.messenger.transport.async),$mailer->send() 实际只是把邮件塞进消息队列,而你没跑 php bin/console messenger:consume,它就永远卡在数据库里。
- 开发阶段建议在
config/packages/mailer.yaml显式禁用异步:transport: 'smtp'(别留null或async) - 删掉已废弃的
spool配置(Symfony 5.3+ 已移除),残留配置会导致静默失败 - 检查
bin/console debug:event-dispatcher,确认没有监听器在mailer.message_sent事件里抛异常——一旦抛了,请求 500,但邮件已经发出,无法回滚
最容易被忽略的是:多传输场景下,X-Transport 头必须加在 Email 实例构建完成之后,不能插在链式调用中间。否则 $email->getHeaders()->addTextHeader('X-Transport', 'alternative') 返回的是 Headers 对象,不是 Email,后续 $mailer->send() 就会类型错误或静默丢弃。


















