使用 PHPMailer 通过 SMTP 发送电子邮件

Posted

技术标签:

【中文标题】使用 PHPMailer 通过 SMTP 发送电子邮件【英文标题】:Sending emails through SMTP with PHPMailer 【发布时间】:2011-04-06 19:57:19 【问题描述】:

我正在尝试使用 phpMailer 发送 SMTP 电子邮件,但我不断收到此错误消息,有什么办法可以摆脱它吗? 我正在尝试通过端口 465 上的 SSL 进行连接。

SMTP -> FROM SERVER: 
SMTP -> FROM SERVER: 
SMTP -> ERROR: EHLO not accepted from server: 

Notice: fputs() [function.fputs]: send of 18 bytes failed with errno=32 Roura přerušena (SIGPIPE) in /home/www/amazonek.cz/subdomains/library/PHPMailer_v5.1/class.smtp.php on line 494
SMTP -> FROM SERVER: 
SMTP -> ERROR: HELO not accepted from server: 

Notice: fputs() [function.fputs]: send of 12 bytes failed with errno=32 Roura přerušena (SIGPIPE) in /home/www/amazonek.cz/subdomains/library/PHPMailer_v5.1/class.smtp.php on line 212
SMTP -> ERROR: AUTH not accepted from server: 
SMTP Error: Could not authenticate.

我的代码:

  require_once('../library/PHPMailer_v5.1/class.phpmailer.php');

        try
            $mail = new PHPMailer(true);
            $mail->IsSMTP();
            $mail->SMTPAuth = true;
            $mail->Host = SMTP_SERVER;
            $mail->Port = SMTP_PORT;
            $mail->Username = SMTP_USERNAME;
            $mail->Password = SMTP_PASSWORD;
            $mail->SMTPDebug = 2;
            $mail->SetFrom(MAIL_ORDERS_ADDRESS, MAIL_ORDERS_NAME);
            $mail->Subject = 'AMAZONEK.cz - objednávka číslo '.$_SESSION['orderId'];
            $mail->Msghtml('<b>Ahoj</b>');
            $mail->AddAddress($_SESSION['user']['email'], $_SESSION['user']['name'].' '.$_SESSION['user']['surname']);
            $mail->AddBCC(MAIL_ORDERS_ADDRESS, MAIL_ORDERS_NAME);

            if(!$mail->Send()) throw new Exception($mail->ErrorInfo);
        
        catch(Exception $e)
            echo $e->getMessage();
        

常量定义:

define('SMTP_SERVER', 'smtp.ebola.cz');
define('SMTP_PORT', 465);
define('SMTP_USERNAME', 'myEmail@myDomain.tld');
define('SMTP_PASSWORD', '***CENSORED***');

define('MAIL_ORDERS_ADDRESS', 'myEmail@myDomain.tld');
define('MAIL_ORDERS_NAME', 'My Name');

有什么想法吗?

【问题讨论】:

【参考方案1】:

据我所知,您的代码一切正常。你的错误是:

SMTP 错误:无法验证。

这意味着您发送的凭据被 SMTP 服务器拒绝。确保主机、端口、用户名和密码正确。

如果您想使用 STARTTLS,请尝试添加:

$mail->SMTPSecure = 'tls';

如果您想使用 SMTPS (SSL),请尝试添加:

$mail->SMTPSecure = 'ssl';

请记住:

某些 SMTP 服务器可以禁止来自“外部”的连接。 某些 SMTP 服务器不支持 SSL(或 TLS)连接。

也许this example 可以提供帮助(GMail 安全 SMTP)。

[Source]

【讨论】:

这实际上有帮助,如果 SMTP 提供商没有指定,我没有意识到我需要 'ssl' 前缀。谢谢。 你也可以在你的主机名前加上协议(即$mail-&gt;Host = "tls://".SMTP_SERVER;)并使用port 465 示例链接已失效。 @ericek111 PHPMailer 似乎已经放弃了他们的网站。更新了存档页面的链接。【参考方案2】:

尝试通过该 SMTP 服务器手动/从交互式邮件程序(例如 Mozilla Thunderbird)发送电子邮件。从错误来看,服务器似乎不会接受您的凭据。那个 SMTP 是在端口上运行,还是 SSL+SMTP?您发布的代码中似乎没有使用安全连接,我不确定 PHPMailer 是否真的支持 SSL+SMTP。

(谷歌搜索您的 SMTP 服务器主机名的第一个结果:http://podpora.ebola.cz/idx.php/0/006/article/Strucny-technicky-popis-nastaveni-sluzeb.html 似乎说“SMTP 邮件发送:安全 SSL 连接,端口:465”。)

看起来 PHPMailer 确实支持 SSL;至少来自this。所以,你需要改变这个:

define('SMTP_SERVER', 'smtp.ebola.cz');

进入这个:

define('SMTP_SERVER', 'ssl://smtp.ebola.cz');

【讨论】:

是的 PHPMailer 支持 SSL (TLS) SMTP。【参考方案3】:

这可能看起来像在黑暗中拍摄,但如果 SMTP 需要 SSL,请确保 PHP 已符合 OpenSSL。

检查使用phpinfo()

希望对你有帮助!

【讨论】:

【参考方案4】:

是的,您需要 OpenSSL 才能正常工作。我的备份测试站点工作,我的实时服务器没有。区别?实时服务器在 PHP 配置中没有 OpenSSL。

【讨论】:

【参考方案5】:

SMTP -> 来自服务器: SMTP -> 从服务器: SMTP -> 错误:服务器不接受 EHLO:

这是尝试使用不使用 SSL 的客户端连接到 SSL 服务的典型情况

SMTP 错误:无法验证。

没有意外启动 SMTP 会话失败 身份验证不是一种选择。

phpmailer 不执行隐式 SSL(又名 TLS on connect,SMTPS) 没有重写 smtp.class.php 以包含对它的支持,因此无法按照您的要求进行操作。

改为使用带有显式 SSL(又名 TLS、STARTTLS)的端口 587。

【讨论】:

【参考方案6】:

我在一个小时内遇到了非常相似的问题,直到我弄清楚出了什么问题。我的问题是,我使用了 SSL,而不是 ssl。检查代码中的区分大小写AlexV 引导我找到问题的根源。那个 helo/ehlo -stuff 似乎无关紧要。

【讨论】:

【参考方案7】:

尝试使用端口 25 而不是 456。

我在使用端口 456 时遇到了同样的错误,将其更改为 25 对我有用。

【讨论】:

【参考方案8】:

带有 tls/ssl smtp STARTTLS 命令的带有 php 流套接字的简单 smtp 客户端: https://github.com/breakermind/PhpMimeParser/blob/master/PhpSmtpSslSocketClient.php

通过身份验证与 gmail.com 一起使用:

<?php
// Login email and password
$login = "your-email@cool.xx";
$pass = "123456";

ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);

$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'verify_peer', false);
stream_context_set_option($ctx, 'ssl', 'verify_peer_name', false);
try
    // echo $socket = stream_socket_client('ssl://smtp.gmail.com:587', $err, $errstr, 60, STREAM_CLIENT_CONNECT, $ctx);
    echo $socket = stream_socket_client('tcp://smtp.gmail.com:587', $err, $errstr, 60, STREAM_CLIENT_CONNECT, $ctx);
    if (!$socket) 
        print "Failed to connect $err $errstr\n";
        return;
    else
        // Http
        // fwrite($socket, "GET / HTTP/1.0\r\nHost: www.example.com\r\nAccept: */*\r\n\r\n");
        // Smtp
        echo fread($socket,8192);
        echo fwrite($socket, "EHLO cool.xx\r\n");
        echo fread($socket,8192);

        // Start tls connection
        echo fwrite($socket, "STARTTLS\r\n");
        echo fread($socket,8192);

        echo stream_socket_enable_crypto($socket, true, STREAM_CRYPTO_METHOD_SSLv23_CLIENT);

        // Send ehlo
        echo fwrite($socket, "EHLO cool.xx\r\n");
        echo fread($socket,8192);

        // echo fwrite($socket, "MAIL FROM: <hello@cool.com>\r\n");
        // echo fread($socket,8192);

        echo fwrite($socket, "AUTH LOGIN\r\n");
        echo fread($socket,8192);

        echo fwrite($socket, base64_encode($login)."\r\n");
        echo fread($socket,8192);

        echo fwrite($socket, base64_encode($pass)."\r\n");
        echo fread($socket,8192);

        echo fwrite($socket, "rcpt to: <to-email@boome.com>\r\n");
        echo fread($socket,8192);

        echo fwrite($socket, "DATA\n");
        echo fread($socket,8192);

        echo fwrite($socket, "Date: ".time()."\r\nTo: <to-email@boome.com>\r\nFrom:<zour-email@cool.xx\r\nSubject:Hello from php socket tls\r\n.\r\n");
        echo fread($socket,8192);

        echo fwrite($socket, "QUIT \n");
        echo fread($socket,8192);

        /* Turn off encryption for the rest */
        // stream_socket_enable_crypto($fp, false);

        fclose($socket);
    
catch(Exception $e)
    echo $e;

【讨论】:

【参考方案9】:

使用 one.com 作为 SMTP 端口 465 不起作用。我可以在 phpmailer 中使用这个配置:

$mail->Host = 'send.one.com';
$mail->SMTPAuth = true;
$mail->Username = "***";
$mail->Password = "******";
$mail->From = "***";
$mail->SMTPAutoTLS = false;
$mail->SMTPSecure = 'none';
$mail->Port = 25;

【讨论】:

以上是关于使用 PHPMailer 通过 SMTP 发送电子邮件的主要内容,如果未能解决你的问题,请参考以下文章

如何在没有 SMTP 的情况下从 PHPMAILER 发送电子邮件

使用php发送电子邮件(phpmailer)

PHPMailer 使用 SMTP 身份验证发送电子邮件,但 Gmail 仍然声称它无法验证发件人

使用 SMTP PHPMailer 将不同的消息发送到不同的电子邮件帐户

PHPMailer 中的“SMTP 错误:无法验证”

使用 phpmailer 从 Gmail 发送电子邮件。登录错误