使用 PHPMailer 处理错误

Posted

技术标签:

【中文标题】使用 PHPMailer 处理错误【英文标题】:Error handling with PHPMailer 【发布时间】:2011-01-24 02:23:02 【问题描述】:

我正在尝试将 phpMailer 用于一个小项目,但我对使用该软件进行错误处理有点困惑。希望有人有这方面的经验。当我设置了电子邮件并使用时:

$result = $mail->Send();

if(!$result) 
    // There was an error
    // Do some error handling things here
 else 
    echo "Email successful";

效果很好,或多或少。问题是当出现错误时,PHPMailer 似乎也会将错误回显,所以如果出现问题,它只会将该信息直接发送到浏览器,基本上会破坏我正在尝试执行的任何错误处理。

有没有办法让这些消息静音?它没有抛出异常,它只是打印出错误,在我的测试用例中是:

invalid address: @invalid@email You must provide at least one recipient email address.

它应该是一个错误,但它应该驻留在 $mail->ErrorInfo;不会被软件回显。

【问题讨论】:

【参考方案1】:

解决 OP 问题:

“PHPMailer 似乎也将错误回显,所以如果出现问题,它只会将该信息直接发送到浏览器,基本上会破坏我正在尝试执行的任何错误处理。”

所有异常都将被馈送到输出缓冲区,这并不明显(无论如何,对我来说,对异常来说是新手)。如果有人在生产中打开调试,前端用户可能会感到惊讶。我不想把它留给机会。另外,异常输出最终出现在(并破坏了)我的 JSON 响应中,因此它实际上阻碍了我的调试。

我的解决方案是在返回前端输出之前清理缓冲区。我的用例是对 fetch API 请求的 JSON 响应,因此在发送输出之前,我调用了ob_clean() 来清理缓冲区中任何不需要的调试数据。例如:

ob_clean(); //clean the buffer
echo json_encode( $public_output ); //echo response to browser

我应该澄清一下,这是对可能不需要的输出的后备,不应替代禁用调试。相反,我想这对于希望在浏览器中看到调试输出的开发人员来说甚至可能是个问题。

$mail->SMTPDebug = SMTP::DEBUG_OFF;

最后,即使禁用调试,有用的错误输出仍然可以发送到日志中:

error_log( $mail->ErrorInfo );

PHPMailer Troubleshooting Wiki on GitHub

【讨论】:

【参考方案2】:

PHPMailer 使用异常。尝试采用以下code:

require_once '../class.phpmailer.php';

$mail = new PHPMailer(true); //defaults to using php "mail()"; the true param means it will throw exceptions on errors, which we need to catch

try 
  $mail->AddReplyTo('name@yourdomain.com', 'First Last');
  $mail->AddAddress('whoto@otherdomain.com', 'John Doe');
  $mail->SetFrom('name@yourdomain.com', 'First Last');
  $mail->AddReplyTo('name@yourdomain.com', 'First Last');
  $mail->Subject = 'PHPMailer Test Subject via mail(), advanced';
  $mail->AltBody = 'To view the message, please use an html compatible email viewer!'; // optional - MsgHTML will create an alternate automatically
  $mail->MsgHTML(file_get_contents('contents.html'));
  $mail->AddAttachment('images/phpmailer.gif');      // attachment
  $mail->AddAttachment('images/phpmailer_mini.gif'); // attachment
  $mail->Send();
  echo "Message Sent OK\n";
 catch (phpmailerException $e) 
  echo $e->errorMessage(); //Pretty error messages from PHPMailer
 catch (Exception $e) 
  echo $e->getMessage(); //Boring error messages from anything else!

【讨论】:

我已经尝试用异常捕获它,我错过的部分是new PHPMailer(true),它实际上启用了异常。感谢您的帮助。 对我来说..这些行有错误..$mail->MsgHTML(file_get_contents('contents.html')); $mail->AddAttachment('images/phpmailer.gif'); // 附件 $mail->AddAttachment('images/phpmailer_mini.gif'); //附件我该如何解决它..谢谢.. 这不好。即使有异常处理,您仍然应该将"Message Sent OK\n"confirmation 放在条件中,否则会导致误导性的确认说在实际出现问题时没关系。所以使用例如:if ( $mail->Send() ) echo "E-mail sent OK<br>"; 在邮件发送成功时使用此代码,他们将返回“资源 ID #7”以及我们的成功消息。有什么解决办法吗? @Fabien 其实抛出一个错误意味着Message Sent OK这一行不会到达【参考方案3】:

只需要自己解决这个问题。以上答案似乎没有考虑到 $mail->SMTPDebug = 0; 选项。首次提出问题时,它可能不可用。

如果您从 PHPMail 站点获取代码,则默认为 $mail->SMTPDebug = 2; // enables SMTP debug information (for testing)

https://github.com/Synchro/PHPMailer/blob/master/examples/test_smtp_gmail_advanced.php

将该值设置为 0 以抑制错误并按照上述说明编辑代码的“catch”部分。

【讨论】:

如果还是不行,请选择$mail->SMTPDebug = 4; - 这将显示 PHPMailer 所做的每一步【参考方案4】:

您可以使用$mail->ErrorInfo 方法获取有关错误的更多信息。例如:

if(!$mail->send()) 
    echo 'Message could not be sent.';
    echo 'Mailer Error: ' . $mail->ErrorInfo;
 else 
    echo 'Message has been sent';

这是您需要使用new PHPMailer(true) 激活的异常模型的替代方法。但如果可以使用异常模型,请将其用作@Phil Rykoff 的答案。

来自githubhttps://github.com/PHPMailer/PHPMailerPHPMailer主页。

【讨论】:

我喜欢这个,因为你不必传递构造函数参数也不必捕获异常。【参考方案5】:

请注意!!!实例化PHPMailer时必须使用如下格式!

$mail = new PHPMailer(true);

如果你不忽略异常,你唯一能得到的就是例程的回声!我知道这是在创建之后很好,但希望它会对某人有所帮助。

【讨论】:

@WOUNDEDStevenJones 我为接受的答案而苦苦挣扎。也许我读得不够仔细,但无论哪种方式,这个答案都对我有帮助。【参考方案6】:
$mail = new PHPMailer();

$mail->AddAddress($email); 
$mail->From     = $from;
$mail->Subject  = $subject; 
$mail->Body     = $body;

if($mail->Send())
    echo 'Email Successfully Sent!';
else
    echo 'Email Sending Failed!';

处理电子邮件发送成功或失败的最简单方法...

【讨论】:

您应该将 $mail->ErrorInfo 附加到 else 大小写以显示错误。 这是原始问题的起点 - 仅提出问题,因为这还不够。【参考方案7】:

在PHPMailer.php中,有如下几行:

echo $e->getMessage()

只需评论这些行,您就可以开始了。

【讨论】:

【参考方案8】:

这个很好用

use try  as above

use Catch as above but comment out the echo lines
 catch (phpmailerException $e)  
//echo $e->errorMessage(); //Pretty error messages from PHPMailer
 catch (Exception $e)    
//echo $e->getMessage(); //Boring error messages from anything else!

然后添加这个

if ($e) 
//enter yor error message or redirect the user
 else 
//do something else 

【讨论】:

【参考方案9】:

即使您使用异常,它仍然会输出错误。您必须将 $MailerDebug 设置为 False,应该如下所示

$mail = new PHPMailer();
$mail->MailerDebug = false;

【讨论】:

请注意这已被删除:版本 1.25(2001 年 7 月 2 日星期一) * 通过添加 $ErrorInfo 变量改进了错误处理 * 删除了 MailerDebug 变量(新错误处理程序已过时)【参考方案10】:

我们编写了一个封装类来捕获缓冲区并将打印输出转换为异常。这让我们可以升级 phpmailer 文件,而不必记住每次升级时都注释掉 echo 语句。

包装类的方法类似于:

public function AddAddress($email, $name = null) 
    ob_start();
    parent::AddAddress($email, $name);
    $error = ob_get_contents();
    ob_end_clean();
    if( !empty($error) ) 
        throw new Exception($error);
    

【讨论】:

以上是关于使用 PHPMailer 处理错误的主要内容,如果未能解决你的问题,请参考以下文章

phpmailer / sendmail返回错误“对等连接重置”

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

phpmailer错误“无法实例化邮件功能”

在 PHPMailer 上出现错误 405(不允许)

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

通过 PHPMailer 发送电子邮件时出现身份验证错误