提问者:小点点

[SMTP:连接套接字失败: fsokopen():无法连接到ssl://smtp.gmail.com:465(未知错误)(代码:-1,响应:)]


在过去的两个月里,我一直在解决这个问题,但没有得到如何解决这个问题的结果。我使用PHP 5.6.3与PEAR 1.10.1,有问题的电子邮件页面与我们的三方电子邮件软件在我们的本地服务器上运行良好,仅为SMTP使用端口25。现在,PHP页面确实引用了一个包含所有主机、密码和用户名信息的XML模板。我想切换到使用SSL的谷歌电子邮件服务器。我实现了我的电子邮件管理员提供的更改,并相应地更改了MX记录。它正常运作了两周。之后,我得到以下错误

"连接到ssl://smtp.gmail.com:465失败[SMTP:连接套接字失败: fsokopen():无法连接到ssl://smtp.gmail.com:465(未知错误)(代码:-1,响应:)]"。

我已经更改了几次代码,我删除了ssl://,我已经将协议类型更改为端口号为587的TLS,等等。什么都没起作用!我联系了承包商,用gmail服务器配置构建了一个简单的硬编码页面,上面写着你好世界。他拒绝了,让我自己做了一个简单的PHP页面,请注意,到目前为止,我在PHP编程方面没有任何背景,所以在一个侧面上,我非常高兴这是我的方式,但不管怎样,我还是完成了任务。我有一个页面,发送一个简单的消息,使用smtp服务器与使用PHPMailer库所需的帐户。(见下面的代码)

 <?php  


require_once 'C:\Webpage\PHPMailer-5.2-stable/PHPMailerAutoload.php';

$mail = new PHPMailer();
$mail->isSMTP();
$mail->SMTPAuth = true;
$mail->SMTPDebug = SMTP::DEBUG_SERVER;
$mail->SMTPDebug   = 4; // 2 to enable SMTP debug information


$mail->Host = 'smtp.gmail.com';
$mail->Username = 'username@gmail.com';
$mail->Password = 'XXXXXXXXXXXXXXXXXXX';
$mail->SMTPSecure ='ssl';
$mail->Port = 465;

/*$mail->SMTPOptions = array(
    'ssl' => array(
        'verify_peer' => false,
        'verify_peer_name' => false,
        //'allow_self_signed' => true
    )
);*/

$mail->From = 'XXXXt@abc.com';
$mail->FromName = 'Example';
$mail->addReplyTo('testing@abc.com','Example');
$mail->AddAddress('user1@xyz.com', 'John Doe');


$mail->Subject = 'Hello World';
$mail->Body ='A test email!';
$mail->AltBody = 'A test email!';



 if(!$mail->Send()) {
    echo "Mailer Error: " . $mail->ErrorInfo;
 } else {
    echo "Message has been sent";
 }
        ?>

现在我知道这不是用梨,但从中我发现了一些有趣的信息,我认为是相关的。该代码仅在具有

 $mail->SMTPOptions = array(
        'ssl' => array(
            'verify_peer' => false,
            'verify_peer_name' => false,
            //'allow_self_signed' => true
        )
);

不是注释掉它的工作原理,但当它被注释掉,我收到一个关于这个的错误。

Connection failed. Error #2: stream_socket_client(): SSL operation failed with code 1. OpenSSL Error messages:error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed [C:\Webpage\PHPMailer-5.2-stable\class.smtp.php line 299]

所以我在谷歌上搜索了这个错误,并被引导到php。用于更改openssl的ini文件。cafile和openssl。capath值。我输入了下载CA证书并输入了值的正确路径,但它仍然不起作用。我放错地方了吗?或者使用PEAR库是否有更简单的方法来解决此问题?请在此问题上提供任何帮助,我们将不胜感激!:)

更新(2018年2月20日):

我已经下载了包,并将路径设置为正确的位置,curl.cainfo="C:\OpenSSL-Win64\bin\PEM\cacert.pem"openssl.cafile="C:\OpenSSL-Win64\bin\PEM\cacert.pem"。我仍然得到的错误,我运行以下检查ssl位置,看看它是否使用php.ini文件,并得到以下结果。

    <?php
 error_reporting(E_ALL);

print "\nIf you've got this far without errors then problem is with your SSL config\n";
 $calocns=openssl_get_cert_locations();
 if (count($calocns)) {
     print "Check you've got your cacerts deployed in one of the following locations\n";
     foreach ($calocns as $k=>$v) print "$k = $v\n";
 } else {
     print "You've not configured your openssl installation on this host\n";
 }
$calocns=openssl_get_cert_locations();
//var_dump(openssl_get_cert_locations());


?>

结果:

    If you've got this far without errors then problem is with your SSL config Check you've got your cacerts deployed in one of the following locations default_cert_file = f:\repo\winlibs_openssl_vc11_x86/cert.pem default_cert_file_env = SSL_CERT_FILE 
    default_cert_dir = f:\repo\winlibs_openssl_vc11_x86/certs 
    default_cert_dir_env = SSL_CERT_DIR 
    default_private_dir = f:\repo\winlibs_openssl_vc11_x86/private
 default_default_cert_area = f:\repo\winlibs_openssl_vc11_x86 
    ini_cafile = 
    ini_capath = 

我似乎做得不对,或者需要知道如何更改位置,因为这些位置在我的计算机上不存在,我不明白在我更改配置文件本身中的路径时,默认情况下这些位置是如何变化的。有什么想法吗?


共1个答案

匿名用户

显然,这仍然是证书问题。尝试使用从Mozilla提取的最新CA证书。只需下载它,将它放在某个地方或替换当前的cacert即可。perm,将证书路径添加到openssl。cafile卷曲。在php中使用cainfo。ini,然后重试。您可能需要对openssl进行注释。现在请看capath。

您可以在PHPMailer疑难解答Wiki中阅读更多关于CA证书相关问题的信息。

2018年2月20日更新:

curl.cainfoopenssl.cafile路径看起来很好,假设这是您下载的cacert.pem的正确路径。但是,当您运行openssl_get_cert_locations()时,您的ini_cafile是空的。它应该反映您在openssl.cafile中设置的任何内容。在对php.ini进行更改后,您需要重新启动Web服务器(Apache/nginx)才能生效。重启后,通过运行phpinfo()检查openssl.cafile值,并确保它是正确的。

我不知道为什么默认的证书目录是这样的。可能是以前安装的开放式SSL?无论哪种方式,它对我来说也是一个不存在的默认路径,但这并不重要,因为我的ini\u cafile显示的值与我在openssl中定义的值相同。cafileopenssl\u get\u cert\u locations()显示了它将查找证书的位置列表,所以如果正确的位置在其中,我认为应该可以。