如何捕获由mail()函数引起的错误?

29

请问有人知道在php中如何捕捉邮件错误(发送邮件时显示的错误由邮件服务器故障引起)?

由邮件服务器故障引起的错误如下:

<!--2010-02-24T14:26:43+11:00 注意 (5):意外错误:mail() [<a href='function.mail'>function.mail</a>]: Failed to connect to mailserver at "ip " port portip, verify your "SMTP" and "smtp_port" setting in php.ini or use ini_set() (# 2).
2010-02-24 14:26:43
用户名:admin
文件D:\test.php的第439行出错
脚本:/customer.php
[全局错误处理器]
-->


1
你如何发送邮件?你是直接与SMTP服务器通信吗? - Goran Rakic
5个回答

48

这大概是你能做到的最好程度:

if (!mail(...)) {
   // Reschedule for later try or panic appropriately!
}

http://php.net/manual/zh/function.mail.php

mail()函数返回TRUE表示邮件成功接收并准备发送,返回FALSE则表示邮件无法正确发送。

需要注意的是,仅仅因为邮件已经被接收并准备发送,并不意味着该邮件一定会成功到达预期目的地。

如果您需要屏蔽警告,可以使用:

if (!@mail(...))

使用 @ 运算符时要小心,如果没有适当的检查是否成功,则可能会出现问题。


如果无法抑制 mail() 中的错误(奇怪的是,目前不能测试它),你可以:

a)暂时关闭错误:

$errLevel = error_reporting(E_ALL ^ E_NOTICE);  // suppress NOTICEs
mail(...);
error_reporting($errLevel);  // restore old error levels

b) 根据 fireMike 的建议,使用不同的邮件程序。

如果 mail() 太不稳定和不灵活,可以考虑 b)。关闭错误提示会增加调试难度,通常不是一个好习惯。


3
+1,好的答案。人们常常忘记mail()函数返回一个布尔值。很好,你还提及了“如果没有错误,邮件就已送达”的假设,因为这也是新开发人员中常见的误解。 - Sampson
嗨deceze,我知道mail()会返回true或false。但不知何故,这总是在我的页面上显示错误消息(该错误消息显示在我上面的问题中,只有在我查看页面的源代码时才能查看错误):而且这个错误导致我无法重定向(header())我的页面到新页面。我已经搜索了代码,但无法找出实际上显示此错误的位置。也许这是在php stmp设置中设置的? - Jin Yong
我的问题是... 我该如何忽略或抛弃页面标题中的“无法连接到邮件服务器”错误信息?有人有什么想法吗?我在谷歌上搜索了很久,但仍然无法找到解决方法。 - Jin Yong
非常感谢,这对我很有用。需要注意的一点是要正确设置头信息。$headers = 'From: ' .$email . "\r\n". 'Reply-To: ' . $email. "\r\n" . 'X-Mailer: PHP/' . phpversion();mail($email_to, $subject, $message, $headers); - Glen

7

PHPMailer可以很好地处理错误,是通过SMTP发送邮件的良好脚本...

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

如果您没有将异常属性设置为true,实际上我认为它会回显一个错误。 - AntonioCS
我深入研究了它的代码,发现它只是使用临时的“安全模式”+ @mail() 来处理错误。 - Wojtek Mazurek

5

同时使用http://php.net/error_get_last也不能帮助你解决问题,因为mail()函数不会将其错误输出到该函数中。

唯一的方法似乎是使用适当的邮件发送程序,就像上面已经建议的那样。


2
这个说法似乎有一定的价值,“mail”对我返回false,但“error_get_last”为空。 - nuala

3

这不是根据手册,而是根据手册中的注释,它确实是误导性的,永远不应该使用它。最后的错误可能在代码的某个地方被弃用通知,如果正确设置,它不会中断执行,特别是在生产环境中。 - CT.

1
你可以使用PEAR Mail类和方法,这样可以通过以下方式检查错误:
if (PEAR::isError($mail)) {
    echo("<p>" . $mail->getMessage() . "</p>");
} else {
    echo("<p>Message successfully sent!</p>");
}

您可以在这里找到一个例子 这里


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接