我正在使用SMTP PRO(https://www.magentocommerce.com/magento-connect/smtp-pro-email-free-custom-smtp-email.html)配置Magento 1.9.1以使用外部SMTP发送电子邮件。
我已经设置了配置(主机名,端口,用户名,密码),但是当我尝试发送测试电子邮件时,它失败了,并且无法打开套接字'错误信息。如果我深入研究代码,我发现错误是从lib / Zend / Mail / Protocol / Abstract.php中的这段代码生成的:
$this->_socket = @stream_socket_client($remote, $errorNum, $errorStr, self::TIMEOUT_CONNECTION);
if ($this->_socket === false) {
if ($errorNum == 0) {
$errorStr = $remote.' Could not open socket '.phpversion();
}
/**
* @see Zend_Mail_Protocol_Exception
*/
#require_once 'Zend/Mail/Protocol/Exception.php';
throw new Zend_Mail_Protocol_Exception($errorStr);
}
我的PHP环境(5.6.30)具有openssl支持(请参阅下面的图片和摘要)
[root@ns3023903 httpdocs]# php -r 'print_r(stream_get_transports());'
Array
(
[0] => tcp
[1] => udp
[2] => unix
[3] => udg
[4] => ssl
[5] => sslv3
[6] => sslv2
[7] => tls
)
没有防火墙问题,因为我可以在端口465上远程登录到目标主机,或使用 phpmailer 使用相同的SMTP与我用来运行站点虚拟主机的同一用户发送电子邮件。
我在CentOS 7 64位服务器上,禁用了SELinux,如果这很重要,我使用Plesk 12配置虚拟主机。
名称解析也正常工作(我可以正确ping通SMTP名称并查找IP地址)。
我显然在这里遗漏了什么...但是什么?
答案 0 :(得分:2)
事实证明,根据stream_socket_client()假设的默认选项,它在PHP版本5.6.30中发生了变化。
首先,在Magento核心代码中的stream_socket_client调用之前摆脱愚蠢的@之前,我实际上无法理解发生了什么。我甚至不接近PHP开发人员所以我一直忘记那个愚蠢的@前缀是什么(说实话我甚至不知道为什么它存在)。
删除@后我看到了这个:
Warning: stream_socket_client(): Peer certificate CN=`*.aruba.it' did not match expected CN=`mail.myclientreserveddomain.com'
我在PHP文档中看了一下,我发现了核心代码的两行差异(我知道这不对,我现在将重构它,但我想先分享快速的解决方法)。
基本上我正在创建一个上下文并使用另一个版本的stream_socket_client调用
$context = stream_context_create(['ssl' => [
'verify_peer' => false,
'verify_peer_name' => false
]]);
// open connection
$this->_socket = stream_socket_client($remote, $errorNum, $errorStr, 120, STREAM_CLIENT_CONNECT, $context);
跳过对等名称验证是关键。不确定为什么/如何/何时从php pre 5.6.30更改为PHP 5.6.30(我说过我不是PHP开发人员吗?)但它确实有效。我还尝试在PHP 5.4.x下运行原始代码,它没有解决方法,所以肯定是这样。