ThinkPHP发送邮件需确保模板样式内联且字符集为UTF-8、base64编码,多语言须手动加载语言包并传入翻译后变量,禁用运行时lang()调用;推荐Twig引擎替代原生模板,SMTP配置须匹配端口/加密方式并启用调试。

ThinkPHP 发送邮件不是简单调用一个方法就完事,关键在模板渲染方式和发送上下文环境两个环节。直接用 lang() 或外链 CSS 的模板,90% 会出问题——要么乱码、要么空白、要么被当垃圾邮件。
HTML 邮件模板必须内联样式
所有主流邮件客户端(Outlook、Apple Mail、QQ邮箱等)基本不支持 <style></style> 标签或外部 CSS 文件。哪怕你用了 Bootstrap 类名,也得手动转成行内 style。
- 模板路径建议统一放在
view/email/下,比如verify.html - 渲染时用
$this->fetch('email/verify', ['code' => $code]),不要用view()直接输出到浏览器那种逻辑 - 每个标签都得带
style属性:<p style="font-size:14px;color:#333;">验证码:{$code}</p> - 务必设置:
$mail->CharSet = 'UTF-8'; $mail->Encoding = 'base64';,缺一不可
多语言邮件不能依赖 lang() 函数
邮件常在队列、命令行或定时任务中发送,此时没有 HTTP 请求上下文,lang() 会返回空字符串甚至报错,而且毫无提示。
- 先读取用户语言偏好,比如
$locale = $user->lang ?: 'zh-cn' - 主动加载语言包:
Lang::load(APP_PATH . 'lang/' . $locale . '.php'); - 用
Lang::get('email_verify_title')提前翻译好,再传进模板:view('email/verify', ['title' => $title, 'body' => $body]) - 模板里只输出变量:
<h2>{$title}</h2> <p>{$body}</p><div class="aritcle_card flexRow"> <div class="artcardd flexRow"> <a class="aritcle_card_img" href="/xiazai/skill5233" title="btpanel phpsite 宝塔面板PHP网站"><img src="https://img.php.cn/upload/skill/000/000/081/179040786932301.jpg" alt="btpanel phpsite 宝塔面板PHP网站" ></a> <div class="aritcle_card_info flexColumn"> <a href="/xiazai/skill5233" title="btpanel phpsite 宝塔面板PHP网站">btpanel phpsite 宝塔面板PHP网站</a> <p>宝塔面板 PHP 网站管理:站点创建、删除、启停、PHP 版本切换、域名管理、SSL证书管理、伪静态管理、数据库管理</p> </div> <a href="/xiazai/skill5233" title="btpanel phpsite 宝塔面板PHP网站" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span> </a> </div> </div> <p><span>立即学习</span>“<a href="https://pan.quark.cn/s/7fc7563c4182" style="text-decoration: underline !important; color: blue; font-weight: bolder;" rel="nofollow" target="_blank">PHP免费学习笔记(深入)</a>”;</p>,不调用任何函数
推荐用 Twig 替代原生模板引擎
ThinkPHP 原生模板对邮件场景支持弱,比如不自动转义 HTML、不强制内联、无变量预编译。Twig 更安全可控,适合纯内容渲染。
- 安装:
composer require twig/twig:^3.0 - 封装一个
TemplateService,指定模板目录为template/email/ - 渲染时传入已翻译的变量:
Twig::render('verify.html', ['code' => $code, 'title' => $title]) - Twig 默认转义 HTML,发邮件时用
{{ body|raw }}输出原始 HTML 内容
SMTP 配置要避开常见坑
别只填账号密码就以为能发——端口、加密方式、时区、字符集,一个错就静默失败。
- QQ 邮箱用
smtp.qq.com+SSL/465,Gmail 用smtp.gmail.com+TLS/587 -
date_default_timezone_set('Asia/Shanghai')必须设,否则部分服务器时间戳异常导致认证失败 - 附件路径必须是英文,中文路径在 PHPMailer 中大概率丢失
- 开发阶段启用
$mail->SMTPDebug = 2,错误信息会直接打印,比看日志快得多


















