帝国cms phpmailer 发送邮件 SMTP Error: could not connect to SMTP host server(s) 错误
微wx笑 2021-08-11【帝国CMS】 3 0关键字: 帝国cms phpmailer 发送邮件 SMTP
最近网站的评论渐渐多了起来,由于评论是需要审核才能显示的,所以希望收到评论后能给自己的邮件发送一封邮件;由于使用的QQ的企业邮箱,可以绑定微信,这样收到邮件后微信就会收到通知,就等于是网站有评论,微信就会收到通知了。但是过程中却遇到了一个大坑!
问题描述
使用帝国cms 7.5 的 phpmailer 发送邮件,没有报任何错误,但就是发送不成功。然后去查看代码文件 e/class/SendMail.inc.php
打到以下代码:
function error_handler($msg) { $this->ErrorInfo = $msg; }
原来是把错误就保存在 $this->ErrorInfo 中了,函数调用只返回 true、false。于是把它打印出来,得到错误信息:SMTP Error: could not connect to SMTP host server(s)
然后就开始排查:
1、邮箱配置,是否开启SMTP
2、服务器 PHP 是否支持 smtp,是否支持SSL
判断 mail 函数是否可用
<?php //php页面为utf编码 header("Content-type: text/html; charset=utf-8"); if (function_exists('mail')) { echo "mail()函数可以使用!"; } else echo "mail()函数不能够使用!"; // phpinfo(); ?>
都没发现问题,smtp 地址配置为 smtp.exmail.qq.com 出现错误 SMTP Error: Could not authenticate 错误
说明邮件服务器是可以连接的,为什么使用 ssl://smtp.exmail.qq.com 的时候就不行了呢?
继续查看代码,有文章提到 class.smtp.php 文件,fsockopen 代码,于是在 SendMail.inc.php 中查找对 class.smtp.php 文件的引用,结果就找到了以下代码:
function smtp_send($header, $body) { // Include SMTP class code, but not twice include_once($this->PluginDir . "class.smtp.php"); $smtp = new SMTP; $smtp->do_debug = $this->SMTPDebug; // Try to connect to all SMTP servers $hosts = explode(";", $this->Host); $index = 0; $connection = false; $smtp_from = ""; $bad_rcpt = array(); $e = ""; // Retry while there is no connection while($index < count($hosts) && $connection == false) { if(strstr($hosts[$index], ":")) list($host, $port) = explode(":", $hosts[$index]); else { $host = $hosts[$index]; $port = $this->Port; } if($smtp->Connect($host, $port, $this->Timeout)) $connection = true; //printf("%s host could not connect<br>", $hosts[$index]); //debug only $index++; } if(!$connection) { $this->error_handler("SMTP Error: could not connect to SMTP host server(s)"); return false; }
也看到了代码中的错误提示:SMTP Error: could not connect to SMTP host server(s)
开始分析代码逻辑,问题聚焦在
list($host, $port) = explode(":", $hosts[$index]);
配置的 host 是 ssl://smtp.exmail.qq.com,经过它这么一搞,最终连接的时候“if($smtp->Connect($host, $port, $this->Timeout))”,打印出来发现,$host 变成了 “ssl”,这样子怎么可能连接成功呢!
解决方法:
干掉 list($host, $port) = explode(":", $hosts[$index]);
while 代码块改成这样:
// Retry while there is no connection while($index < count($hosts) && $connection == false) { $host = $hosts[$index]; $port = $this->Port; if($smtp->Connect($host, $port, $this->Timeout)) $connection = true; //printf("%s host could not connect<br>", $hosts[$index]); //debug only $index++; }
终于邮件发送成功了。
后台参数配置
本文由 微wx笑 创作,采用 署名-非商业性使用-相同方式共享 4.0 许可协议,转载请附上原文出处链接及本声明。
原文链接:https://www.ivu4e.cn/blog/EmpireCMS/2021-08-11/719.html