PHP 7.1.x升级后PHPMailer邮件发送失败(证书相关报错)
解决PHP 7.1.x下PHPMailer TLS 25端口发送邮件报错
stream_socket_enable_crypto的问题 这个问题我之前帮不少开发者排查过,核心原因是PHP 7.1版本开始大幅收紧了SSL/TLS的证书验证规则——在PHP 5.5时代,默认的验证逻辑比较宽松,甚至可能跳过了证书校验,所以你的内部自签名证书SMTP服务器能正常工作;但升级到PHP 7.1后,系统默认会强制验证证书的有效性,导致加密握手失败,抛出stream_socket_enable_crypto错误。
下面给你几个针对性的解决方案,按安全性从高到低排序:
1. 导入内部SMTP证书到PHP信任列表(推荐生产环境使用)
如果你的内部SMTP服务器用的是自签名证书,最安全的做法是把它加入PHP的可信CA列表:
- 先导出SMTP服务器的证书:
在终端执行以下命令(替换your-smtp-server为你的服务器地址):openssl s_client -connect your-smtp-server:25 -starttls smtp < /dev/null | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > smtp-internal.crt - 找到PHP的配置文件(比如
php.ini),修改或添加以下配置:
或者把证书内容追加到系统默认的CA证书文件中(比如Linux下的curl.cainfo = "/path/to/smtp-internal.crt" openssl.cafile = "/path/to/smtp-internal.crt"/etc/ssl/certs/ca-certificates.crt,Windows下的c:\php\extras\ssl\cacert.pem) - 重启PHP-FPM或Web服务器,让配置生效。
2. 临时关闭PHPMailer的证书验证(仅内部测试环境使用)
如果是内部测试场景,且能确保SMTP服务器的安全性,可以临时关闭证书验证来快速解决问题:
在你的PHPMailer配置代码中添加以下选项:
$mail->SMTPOptions = array( 'ssl' => array( 'verify_peer' => false, 'verify_peer_name' => false, 'allow_self_signed' => true ) );
verify_peer:关闭对SSL证书颁发者的验证verify_peer_name:关闭对证书主机名与服务器地址匹配的验证allow_self_signed:允许使用自签名证书
⚠️ 注意:这个方法会降低通信安全性,绝对不要在对外的生产环境中使用。
3. 升级PHPMailer到兼容PHP 7.1的版本
如果你的PHPMailer版本比较旧,可能存在与PHP 7.1的兼容性问题。建议升级到PHPMailer 6.x版本(完全兼容PHP 7.0+),或者至少升级到5.2.27以上的5.x版本(对PHP 7.1有基本支持)。
额外排查步骤
你可以先通过命令行测试SMTP服务器的TLS连接是否正常,确认问题根源:
openssl s_client -connect your-smtp-server:25 -starttls smtp
如果输出中包含verify return code: 18 (self signed certificate),就可以100%确认是自签名证书未被信任导致的问题。
内容的提问来源于stack exchange,提问作者AmazingTrans
相关产品推荐
相关产品推荐

