Zend Framework无法打开ssl socket(Abstract.php)

时间:2017-06-14 14:43:40

标签: php email magento ssl zend-framework

我正在使用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支持(请参阅下面的图片和摘要) SSL Support

[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地址)。

我显然在这里遗漏了什么...但是什么?

1 个答案:

答案 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下运行原始代码,它没有解决方法,所以肯定是这样。