SMTP连接失败主因是Host/Port配置错误或未启用SSL/TLS;认证失败多因用登录密码而非授权码;发信被拒或入垃圾箱系DNS缺少SPF等记录;中文乱码需确保CharSet、文件编码、PHPMailer版本统一。

SMTP连接被拒绝:检查SMTPHost和SMTPPort是否匹配服务商实际要求
很多失败直接卡在TCP连不上,不是密码错,而是端口或域名填错了。比如腾讯企业邮箱必须用smtp.exmail.qq.com,填smtp.qq.com会连通但认证失败;163邮箱要求SMTPPort为465(SSL)或994(TLS),填25在大多数云服务器上会被拦截。
- 国内主流邮箱的正确组合:
SMTPHost=smtp.exmail.qq.com+SMTPPort=465(SSL);SMTPHost=smtp.163.com+SMTPPort=465(SSL)或994(TLS) - ThinkPHP 6 的
think\facade\Mail默认不启用SSL/TLS,必须显式设SMTPSecure='ssl'或'tls' - 阿里云/腾讯云ECS默认封禁
25端口,即使配置正确也会报Connection refused,别白费时间调密码
PHPMailer报错SMTP Error: Could not authenticate:确认账号、密码、授权码三者关系
错误提示说“认证失败”,但真正原因常是用了邮箱登录密码而非“客户端专用密码”——尤其是开启二次验证后,原始密码已无效。
- QQ/腾讯企业邮箱:必须在邮箱设置里开启“POP3/IMAP/SMTP服务”,再生成“授权码”,填进
SMTPUser和SMTPPass - 163邮箱:需在“设置→POP3/SMTP/IMAP”中开启SMTP服务,并勾选“客户端授权码”,用授权码当密码,不是登录密码
- ThinkPHP 6 中
SMTPUser必须是完整邮箱地址(如admin@domain.com),不能只写用户名 - 授权码含大小写字母+数字,复制时容易漏掉末尾空格或换行,建议粘贴后用
strlen()核对长度
发送成功但收件箱看不到邮件:检查From地址与发信域名DNS记录
邮件进了垃圾箱,或者根本没发出,往往不是代码问题,而是发信身份不被信任。Gmail、Outlook等会查SPF、DKIM、DMARC记录,缺一不可。
- 如果用
admin@yourdomain.com发信,你的域名yourdomain.com必须有SPF记录,例如:v=spf1 include:smtp.exmail.qq.com ~all - 腾讯企业邮箱后台可一键生成SPF,但需要你手动加到域名DNS解析里;没配的话,
From字段再合法也会被拒收或打入垃圾箱 - 测试阶段可用
test@example.com这类非真实域名发信,但仅限本地调试;上线前务必换回你自己的域名并补全DNS - ThinkPHP中
Mail::to()->from()里的from()参数必须和SMTPUser一致,否则部分服务商(如阿里云邮件推送)会直接拦截
ThinkPHP 6 调用PHPMailer时中文乱码或附件损坏:注意CharSet和Encoding的组合
乱码不是编码设错了,而是CharSet和内容实际编码不匹配,或者附件二进制流被PHPMailer自动转码了。
立即学习“PHP免费学习笔记(深入)”;
- 正文含中文时,必须同时设
CharSet='utf-8'且HTML内容本身是UTF-8编码(文件保存格式也要是UTF-8无BOM) - 附件用
addAttachment()传路径即可,别用file_get_contents()再传内容——PHPMailer会自动处理二进制流,手动读取反而可能触发转码 - 若用
view()渲染模板发信,确保模板文件本身是UTF-8无BOM,否则mb_convert_encoding()也救不回来 - 某些旧版PHPMailer(如v5.2)对UTF-8支持不稳,推荐锁定使用
phpmailer/phpmailer:^6.8,避免兼容性坑



















