PHPMailer是发送邮件的首选方案,因mail()函数不支持SMTP认证、TLS/SSL加密及错误码响应,易导致静默失败;必须配置isSMTP()、SMTPAuth、SMTPSecure与Port四要素匹配,并使用邮箱授权码而非登录密码,同时设CharSet='UTF-8'并调用isHTML(true)处理HTML邮件。

PHPMailer,别从原生 socket 或 mail() 函数起步——90% 的初学者卡在认证失败、乱码、被拒收、无报错静默失败上,根源是绕开了协议细节和现代邮箱的安全策略。
为什么不能直接用 PHP 的 mail() 函数发 SMTP 邮件
mail() 本质是调本地 sendmail 或 Windows 的 SMTP 服务,不走真正的 SMTP 认证流程。它无法设置用户名/密码、不支持 TLS/SSL 握手、无法响应 535/530 等关键错误码。
常见现象包括:
- 本地开发环境能发,上线后
mail()返回true但收不到邮件(服务器没装 sendmail 或禁用了) - QQ 邮箱提示“发信失败:535 Error: authentication failed”,而你代码里根本没写登录逻辑
- 邮件进垃圾箱,因为缺少
DKIM、SPF头,且From域名和实际发信 IP 不匹配
结论:mail() 只适合内网通知类场景,对外服务必须走显式 SMTP 连接。
PHPMailer 初始化时必须设对的 4 个关键属性
不是填完 Host 和 Port 就完事。以下四点任一出错都会导致连接中断或认证拒绝:
立即学习“PHP免费学习笔记(深入)”;
-
$mail->isSMTP()—— 必须显式调用,否则仍走mail()回退路径 -
$mail->SMTPAuth = true—— QQ/163/Gmail 全部强制要求,设为false会直接 530 错误 -
$mail->SMTPSecure = 'ssl'或'tls'—— 端口和加密方式要配对:465 →ssl,587 →tls;混用必连不上 -
$mail->Port必须和SMTPSecure一致 —— 比如设了SMTPSecure = 'tls'却用 465 端口,connect()会超时
示例(QQ 邮箱):
$mail->Host = 'smtp.qq.com'; $mail->Port = 465; $mail->SMTPSecure = 'ssl'; // 注意这里不是 'tls' $mail->SMTPAuth = true; $mail->Username = 'your@qq.com'; $mail->Password = 'your_app_password'; // 不是邮箱登录密码!
授权码不是邮箱密码,且各平台开启路径完全不同
所有主流邮箱(QQ/163/Gmail)已停用“邮箱密码”作为 SMTP 登录凭证,必须用「授权码」或「应用专用密码」。这个环节踩坑最多:
- QQ 邮箱:设置 → 账户 → “POP3/IMAP/SMTP/Exchange/CardDAV/CalDAV服务” → 开启 SMTP 并生成授权码
- 163 邮箱:设置 → POP3/SMTP/IMAP → 开启 SMTP 服务 → “客户端授权码”处生成(非登录密码)
- Gmail:Google 账户 → 安全 → 两步验证 → 应用专用密码 → 选“邮件”生成 16 位密钥
注意:Password 字段填的是这个授权码,不是你天天输的邮箱密码。填错只会返回模糊的 SMTP Error: Could not authenticate.,没有具体提示。
发 HTML 邮件时 Content-Type 和换行符必须手动控制
PHPMailer 默认发纯文本,HTML 内容需主动声明格式,否则 Outlook / Apple Mail 会把 <h1> 当作明文显示:
- 必须设
$mail->isHTML(true),否则$mail->Body里的标签会被转义或忽略 - 避免在
$mail->Body中拼接 \n 换行 —— HTML 邮件应使用<br>或 CSS,纯文本换行符在 HTML 模式下无效 - 中文标题乱码?给
$mail->Subject加=?UTF-8?B?编码前缀太麻烦,直接用$mail->CharSet = 'UTF-8'更稳妥
最容易被忽略的一点:Gmail/QQ 对单日发送量、新账号首次发信频率有限制。测试阶段别一口气循环发 10 封,先发 1 封,等 2 分钟再试第二封,否则可能触发风控临时封禁 SMTP 权限。



















