【问题标题】:How to handle transient/intermittent PHPMailer SMTP connect errors如何处理瞬态/间歇性 PHPMailer SMTP 连接错误
【发布时间】:2021-12-31 03:00:58
【问题描述】:

我搜索了 StackOverflow 和 PHPMailer 问题,但没有成功。永久性 PHPMailer SMTP 连接错误有很多,但我看不到暂时性或间歇性错误。

我正在使用 PHPMailer (6.2) 和 PHP 8.0 从我的远程 Web 服务器向 smtp.office365.com(Microsoft Exchange Online 服务)发送电子邮件。大多数时候它工作正常。

我怀疑由于网络级别或 SMTP 服务器级别的拥塞,我偶尔会看到以下消息:

SMTP 错误:无法连接到服务器:连接被拒绝 (111)

SMTP 错误:连接服务器失败:连接超时

然后:SMTP connect() 失败。

由于与 SMTP 服务器的初始连接远离托管 PHPMailer 脚本的 Web 服务器,这意味着我不能依赖 SMTP 服务器处理电子邮件排队和重试。

我已经输入了一些基本代码来重试 $email-> send 命令,但到目前为止,当 SMTP 连接失败时,这从未成功通过。

我正在寻求如何处理(在 PHPMailer 中)这些暂时性错误的建议?

非常感谢。

我的服务器 PHP 脚本(摘录):

use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
use PHPMailer\PHPMailer\SMTP;

require ($_SERVER['DOCUMENT_ROOT'] . '/vendor/phpmailer/phpmailer/src/Exception.php');
require ($_SERVER['DOCUMENT_ROOT'] . '/vendor/phpmailer/phpmailer/src/PHPMailer.php');
require ($_SERVER['DOCUMENT_ROOT'] . '/vendor/phpmailer/phpmailer/src/SMTP.php');      

// Load Composer's autoloader
require $_SERVER['DOCUMENT_ROOT'] . '/vendor/autoload.php';  
$email = new PHPMailer(true);//True means Throw errors

try {
    //Server settings
    $email->SMTPDebug = SMTP::DEBUG_CONNECTION;
    $debug = '';
    $email->Debugoutput = function($str, $level) {
        $GLOBALS['debug'] .= "$level: $str\n";
    };

    $email->isSMTP(); // Set mailer to use SMTP
    $email->CharSet = 'UTF-8';  //not important
    $email->Host = 'smtp.office365.com'; // Specify main and backup SMTP servers
    $email->SMTPAuth = true; // Enable SMTP authentication
    $email->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS; 
    $email->Port = 587; // TCP port to connect to
    //Authentication
    $email->Username = ‘Myusername’; // SMTP username
    $email->Password = 'mypassword'; // SMTP password - must be App Password from Microsoftt


     //Recipients
      $email->SetFrom(‘MySenderemail’);
      $email->addReplyto(‘Myreplytoemail’, 'No-Reply');
     $email->addAddress( ‘MyTargetemailaddress’);

    // Content
    $email->isHTML(true); 
    $email->Subject   = $mailsubject;
    $email->Body      = $messagebody;
    $email->AltBody = 'This email can only be viewed in HTML. Please contact the SSN IT Coordinator.';

    //Send the email
    $email->send();
    elog($ModuleName . '|' . $authentic . ': ' . 'Mail Sent Successfully ' . ' ' . $mailsubject);
    echo($ModuleName . '|' . $authentic . ': ' . 'Mail Sent Successfully ' . ' ' . $mailsubject);
    return true;

} catch (Exception $e) {
    error_log($email->ErrorInfo);
    error_log($debug);
    if (strpos($email->ErrorInfo, 'SMTP connect() failed') !== false) {
        // Retry sending the email in case it was a transient error
        error_log ($ModuleName . '|' . $authentic . ': ' . 'First attempt at email failed, retrying: ' .  $email->ErrorInfo . ' ' . $mailsubject);
        try {$email->send();} catch (exception $e){
            //Failed second time so send error
            http_response_code(500);
            if (!headers_sent()) {header('HTTP/1.1 500 Internal Server Error');}
            elog($ModuleName . '|' . $authentic . ': ' . 'Retry Mail not sent ' . $mailsubject . $authentic . $e->getMessage());
           die($ModuleName . '|' . $authentic . ': ' . 'Retry Mail not sent ' . $mailsubject . $authentic . $e->getMessage());
        }
    } else {
        //Some error other than SMTP Connect failed so return it.
        http_response_code(500);
        if (!headers_sent()) {header('HTTP/1.1 500 Internal Server Error');}
        error_log ($ModuleName . '|' . $authentic . ': ' . 'Mail NOT SENT ' . $mailsubject . $authentic . $e->getMessage());
        die($ModuleName . '|' . $authentic . ': ' . 'Mail NOT SENT ' . $mailsubject . $authentic . $e->getMessage());
    }
}

【问题讨论】:

    标签: phpmailer


    【解决方案1】:

    您的连接困难似乎与时间因素有关,因此立即重试不太可能比第一次好。我推荐的方法也是 PHPMailer 文档推荐的方法:安装本地邮件服务器并通过它进行中继。它将管理排队、重试、指数回退和退回,并且您的发送脚本将运行得更快。这将比您尝试用 PHP 编写邮件服务器更有效和可靠。

    旁注:由于您使用的是作曲家,您可以删除 PHPMailer 类的那些 require 行; composer 的自动加载器会自动为你加载这些类。

    【讨论】:

    • 谢谢同步。我没有意识到多余的 require 行 - 好提示:-) 我会尝试使用本地邮件服务器,但是当我第一次尝试时,我确实遇到了各种各样的问题。
    猜你喜欢
    • 2017-10-15
    • 2017-01-19
    • 1970-01-01
    • 2017-07-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多