答案:需严格区分transport(传输方式)和default_mailer(默认mailer名称),前者定义底层发送通道,后者必须指向mailers下已声明的键名;发送html邮件须调用html()方法而非text();本地调试推荐smtp://localhost:1025+mailhog;邮件模板不自动继承app等全局变量,需显式注入或仅用context传递参数。

mailer 配置不生效?检查 transport 和 default_mailer 键名
Symfony 7 的 mailer 配置必须严格区分 transport(底层传输方式)和 default_mailer(默认使用的 mailer 名称),这两个键不能混用。常见错误是把 SMTP 配置直接写在顶层 mailer 下,导致容器注入的 MailerInterface 实际使用的是空配置的默认 transport。
- 正确结构:先定义
transports(如smtp、sendmail),再在mailers下引用它 -
default_mailer必须指向mailers中已声明的 key,比如main,而不是 transport 名 - 若用环境变量覆盖,确保
%env(SMTP_HOST)%等变量已加载且非空,否则 transport 初始化失败但无明显报错
发送 HTML 邮件时内容被当作文本?Content-Type 头必须显式设置
Symfony 的 Mailer 默认发送纯文本邮件,即使你传入了 HTML 字符串。它不会自动检测或推断内容类型——这点和 PHPMailer 不同,容易踩坑。
- 必须用
Email::html()方法创建邮件对象,而非Email::text() - 如果手动构造
Email,需调用$email->html($htmlContent),不能只设text()或靠 headers 混淆 - 附件、内嵌图片等高级功能依赖 MIME boundary,仅靠 headers 添加
Content-Type: text/html无效,会破坏 multipart 结构
开发环境发不出邮件?别只改 php.ini,要配 Symfony 的 transport
很多人以为改了 sendmail_path 就能用 mail() 函数,但在 Symfony 7 中,Mailer 组件默认不走 PHP 的 mail(),而是通过独立 transport 层控制。本地调试最稳的方式是用 smtp://localhost:1025 + MailHog 或类似工具。
- 避免在
dev环境硬编码真实 SMTP 凭据;用symfony://default(仅记录日志)或smtp://127.0.0.1:1025更安全 - 若坚持用
sendmailtransport,确认系统已安装并可执行/usr/sbin/sendmail -bs,且权限正常 - 运行
php bin/console debug:container --parameter=mailer.transports可验证 transport 是否被正确解析
邮件模板里用 {{ app.environment }} 报错?Twig 全局变量需显式注入
Symfony 的邮件模板(如 templates/emails/welcome.html.twig)默认不包含 app 这类全局 Twig 变量,因为 Mailer 使用独立的 Twig 环境实例,未自动继承主应用的全局变量配置。
- 解决方案一:在模板中只用传入的变量,如
{{ user.name }},由控制器或 service 显式传递全部所需数据 - 解决方案二:在
config/packages/mailer.yaml中添加twig: { globals: { environment: '%kernel.environment%' } } - 注意:全局变量名不能与模板参数冲突,否则后者会覆盖前者











