云知笔记

PHP5.3升级到7.0版本后用SMTP发送邮件失败的解决方法

很多朋友最近在陆续升级自已主机的PHP到7.0以后的版本,PHP7.0以后的版本的确性能卓越,所以大家都手痒痒,可是升级过后各种问题来了,PHP7.0的默认配置真的需要做很大的改动才能真正发挥出它的强大功能出来。

最近老张就遇到了升级PHP到7.0后,原来好好的SMTP发送邮件配置报错了,本人架设的是DZ,升级过后网站刷刷刷,速度没得说,用户体验真的很棒,可是好景不长,一段时间过后,老张就感觉没有对劲了,本来以为用户体验好了,相对于以前用户注册的频率也会更快一些,然而却是升级为PHP7.0后,居然发现没有一个用户注册进来,老张直觉强烈感到应该是用户注册环节的某个地方出错了,不然不可能一个用户都不注册,因为升级之前一直有用户不定时地注册进来,注册用户一直都是稳步增涨中的,所以老张认为不可能是PHP升级后用户粘度降低的原因,于是老张就试着自已注册看看是哪个技术环节出错了,果然发现问题所在,由于老张设置了DZ新用户必须经过真实邮箱验证,在注册到邮箱验证环节的时候发现自已预留的验证邮箱一直收不到验证邮件,看来这就是问题的症结,想必一大波新用户注册进来由于根本收到验证邮件所以都放弃了,真是气煞老张了,于是开始立马查找原因。

由于PHP升级之前,DZ主机的设置SMTP发送验证邮件一直很正常,而且在升级过后老张没有对DZ后台代码做过一丝改动,数据库也没有动过,连前端样式都没有碰过,所以自然怀疑到PHP升级的原因了,好在主机还保留了PHP5.3版本,所以果断切换回PHP5.3,重新测试SMTP发送,一切正常,验证邮件秒到,畅通无阻,难道这是要老张重新回到低版本的节奏,忍不下这口气,必须要找到原因,好好地发挥PHP7.0的功能,彻底告别PHP5X时代。

于是重新写一个单页PHP,设置好标准的SMTP发送代码,进入调试状态:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
// 引入PHPMailer的核心文件
require_once("PHPMailer/class.phpmailer.php");
require_once("PHPMailer/class.smtp.php");

// 实例化PHPMailer核心类
$mail = new PHPMailer();
// 是否启用smtp的debug进行调试 开发环境建议开启 生产环境注释掉即可 默认关闭debug调试模式
$mail->SMTPDebug = 1;
// 使用smtp鉴权方式发送邮件
$mail->isSMTP();
// smtp需要鉴权 这个必须是true
$mail->SMTPAuth = true;
// 链接qq域名邮箱的服务器地址
$mail->Host = 'smtp.qq.com';
// 设置使用ssl加密方式登录鉴权
$mail->SMTPSecure = 'ssl';
// 设置ssl连接smtp服务器的远程服务器端口号
$mail->Port = 465;
// 设置发送的邮件的编码
$mail->CharSet = 'UTF-8';
// 设置发件人昵称 显示在收件人邮件的发件人邮箱地址前的发件人姓名
$mail->FromName = '发件人昵称';
// smtp登录的账号 QQ邮箱即可
$mail->Username = '12345678@qq.com';
// smtp登录的密码 使用生成的授权码
$mail->Password = '**********';
// 设置发件人邮箱地址 同登录账号
$mail->From = '12345678@qq.com';
// 邮件正文是否为html编码 注意此处是一个方法
$mail->isHTML(true);
// 设置收件人邮箱地址
$mail->addAddress('11111111@qq.com');
// 添加多个收件人 则多次调用方法即可
$mail->addAddress('11111111@163.com');
// 添加该邮件的主题
$mail->Subject = '邮件主题';
// 添加邮件正文
$mail->Body = 'HELLO WORLD';
// 为该邮件添加附件
$mail->addAttachment('./example.pdf');
// 发送邮件 返回状态
$status = $mail->send();

势行上述代码后,果然收到错误提示:missing php_openssl(缺少php_openssl),没有什么比这句错误提示更明确了,肯定是一个叫php_openssl东东没有加载,由此想到了刚升级到PHP7.0后要手动加载很多扩展模块才能正常使用,于是进入php.ini查找是否真有这个东东,不出所料,扩展模块里果然有这个东东被注释了,立马解除注释(即去掉模块代码前面的;号,使其正常执行,如下面php.ini配置代码红色粗体所示那个罪魁祸首:

; Windows Extensions
; Note that ODBC support is built in, so no dll is needed for it.
; Note that many DLL files are located in the extensions/ (PHP 4) ext/ (PHP 5+)
; extension folders as well as the separate PECL DLL download (PHP 5+).
; Be sure to appropriately set the extension_dir directive.
;
;extension=php_bz2.dll
extension=php_curl.dll
extension=php_fileinfo.dll
extension=php_ftp.dll
extension=php_gd2.dll
;extension=php_gettext.dll
;extension=php_gmp.dll
;extension=php_intl.dll
;extension=php_imap.dll
;extension=php_interbase.dll
;extension=php_ldap.dll
extension=php_mbstring.dll
;extension=php_exif.dll ; Must be after mbstring as it depends on it
extension=php_mysqli.dll
;extension=php_oci8_12c.dll ; Use with Oracle Database 12c Instant Client
extension=php_openssl.dll
;extension=php_pdo_firebird.dll
extension=php_pdo_mysql.dll
;extension=php_pdo_oci.dll
;extension=php_pdo_odbc.dll
;extension=php_pdo_pgsql.dll
;extension=php_pdo_sqlite.dll
;extension=php_pgsql.dll
;extension=php_shmop.dll

保存php.ini,重启主机,执行开头的代码,测试邮件秒到,大功告成。

总结:后来老张对深层原因作了详细分析,在PHP7.0的文档中找到了终极原因:As of PHP 5.6 you will get a warning/error if the SSL certificate on the server is not properly configured.(意思是从PHP 5.6开始,如果服务器上的SSL证书未正确配置,您将收到警告/错误。),由于现在大多数SMTP邮件服务器都要求SSL验证,所以PHP发送中都启动了SSL验证方式,在PHP5.6之前不会强制要求SSL证书,所以发送正常,但如果高版本PHP就不会忽略,所以需要开启php_openssl扩展模块。老张的总结拿去不谢,如有错误请大家指正。

发表评论

电子邮件地址不会被公开。

42 ÷ = 6