PHP 8.1 下 PHPMailer 发送失败主因是 Host 混入协议前缀(如 ssl://)、SMTPSecure 与 Port 组合错误(如 587 配 "ssl")、Port 为字符串或 SMTPSecure 大小写/拼写错误(如 "TLS"、"startls")。

PHP 8.1 下 PHPMailer 发送失败,90% 是因为 SMTPSecure 和 Port 的组合不匹配,或者 Host 字符串里混进了协议前缀(比如 ssl://)。这不是 PHP 版本兼容性问题,而是配置逻辑被写错了。
PHPMailer 的 Host 必须是纯域名,不能带 ssl:// 或 tls://
很多人复制网上旧教程,把 $mail->Host 写成 "ssl://smtp.gmail.com" 或 "tls://smtp.qq.com" —— 这在 PHP 8.1 + PHPMailer 6.9+ 会直接导致连接超时或 SMTP connect() failed。
PHPMailer 自己根据 SMTPSecure 和 Port 决定怎么加密,Host 只负责 DNS 解析。加协议前缀会让它尝试连接一个不存在的主机名。
- ✅ 正确:
$mail->Host = "smtp.gmail.com"; - ❌ 错误:
$mail->Host = "ssl://smtp.gmail.com"; - ❌ 错误:
$mail->Host = "tls://smtp.163.com";
SMTPSecure 和 Port 必须严格配对
端口不是随便填的,它和加密方式是绑定的。PHP 8.1 不会帮你“猜”该用哪种加密,错配就断连。
立即学习“PHP免费学习笔记(深入)”;
- 用端口
587→$mail->SMTPSecure = "tls"(显式 STARTTLS) - 用端口
465→$mail->SMTPSecure = "ssl"(隐式 SSL) - 绝对不要:端口
587配"ssl",或端口465配"tls" - 端口
25基本别碰——多数云服务器出站禁用,且不支持隐式加密
示例(Gmail):
$mail->isSMTP(); $mail->Host = "smtp.gmail.com"; $mail->Port = 587; $mail->SMTPSecure = "tls"; // 注意这里是字符串 "tls",不是 "startls" 或 "TLS" $mail->SMTPAuth = true; $mail->Username = "you@gmail.com"; $mail->Password = "your_app_password"; // 不是登录密码,是应用专用密码
PHP 8.1 下容易被忽略的类型与大小写细节
PHP 8.1 对类型更严格,有些旧代码能跑,新环境就挂:
-
$mail->Port必须是整数,不是字符串:587✅,"587"❌(虽然可能凑合过,但不推荐) -
$mail->SMTPSecure只接受小写:"tls"✅,"TLS"❌,"startls"❌(常见拼写错误) - 如果用 Composer 加载,确认引入的是
vendor/autoload.php,不是已废弃的PHPMailerAutoload.php(PHPMailer 6.x 已移除) - QQ/163 邮箱必须用「授权码」,不是账户密码;Gmail 必须开启两步验证并生成应用专用密码
本地开发环境连不上?先绕过 TLS 测试连通性
如果你在本地(如 XAMPP、Docker、Valet)反复失败,先临时关闭加密验证,确认网络和认证没问题:
- 设
$mail->SMTPSecure = ""(空字符串) - 设
$mail->Port = 25(仅测试用,生产禁用) - 同时确保
$mail->SMTPAuth = true且账号密码正确
如果这时能连上,说明问题出在 TLS 握手环节(比如 OpenSSL 版本太低、CA 证书路径不对、防火墙拦截 STARTTLS 升级);如果还是连不上,就是 DNS、网络或认证问题。
真实项目里,别留这种配置。它只用来快速定位是“连不到服务器”还是“连上了但加密失败”。后者往往要查 OpenSSL 扩展是否启用、openssl.cafile 是否指向有效证书 bundle。



















