P粉5187995572023-08-30 09:19:15
虽然此答案的某些部分仅适用于 mail()
函数本身的使用,但其中许多故障排除步骤可以应用于任何 PHP 邮件系统。嗯>
您的脚本未发送电子邮件的原因有多种。除非存在明显的语法错误,否则很难诊断这些事情。如果没有,您需要仔细检查下面的清单,以查找您可能遇到的任何潜在陷阱。
错误报告对于根除代码中的错误以及 PHP 遇到的一般错误至关重要。需要启用错误报告才能接收这些错误。将以下代码放在 PHP 文件的顶部(或主配置文件中)将启用错误报告。
error_reporting(-1); ini_set('display_errors', 'On'); set_error_handler("var_dump");
请参阅如何获得有用的错误PHP 中的消息? — 此答案了解更多详细信息。
mail()
函数这可能看起来很愚蠢,但一个常见的错误是忘记在代码中实际放置 mail()
函数。确保它在那里并且没有被注释掉。
mail()
函数邮件函数采用三个必需参数,以及可选的第四个和第五个参数。如果您对 mail()
的调用没有至少三个参数,它将失败。
如果您对 mail()
的调用没有按正确顺序提供正确的参数,它也会失败。
您的网络服务器应该记录通过它发送电子邮件的所有尝试。这些日志的位置会有所不同(您可能需要询问服务器管理员它们的位置),但通常可以在用户根目录的 logs
下找到它们。里面将是服务器报告的与您尝试发送电子邮件相关的错误消息(如果有)。
端口阻止是大多数开发人员在集成代码以使用 SMTP 发送电子邮件时面临的一个非常常见的问题。并且,这可以在服务器邮件日志中轻松追踪(邮件日志服务器的位置可能因服务器而异,如上所述)。如果您位于共享托管服务器上,则默认情况下端口 25 和 587 仍处于阻止状态。此阻止是由您的托管提供商故意完成的。即使对于某些专用服务器也是如此。当这些端口被阻止时,请尝试使用端口 2525 进行连接。如果您发现该端口也被阻止,那么唯一的解决方案就是联系您的托管提供商以解除对这些端口的阻止。
大多数托管提供商都会阻止这些电子邮件端口,以保护其网络免于发送任何垃圾邮件。
使用端口 25 或 587 进行普通/TLS 连接,使用端口 465 进行 SSL 连接。对于大多数用户,建议使用端口 587 以避免某些托管提供商设置的速率限制。
当错误抑制运算符 @
被添加到 PHP 中的表达式之前,该表达式可能生成的任何错误消息都将被忽略。在某些情况下,需要使用此运算符,但发送邮件不是其中之一。
如果您的代码包含@mail(...)
,那么您可能隐藏了有助于您调试的重要错误消息。删除@
并查看是否报告任何错误。
仅当您使用error_get_last()
紧接着具体失败。
mail()
返回值mail()
函数:
这一点值得注意,因为:
FALSE
返回值,您就知道错误在于您的服务器接受您的邮件。这可能不是编码问题,而是服务器配置问题。您需要与系统管理员联系以找出发生这种情况的原因。TRUE
返回值,并不意味着您的电子邮件一定会发送。这仅意味着电子邮件已通过 PHP 成功发送到服务器上相应的处理程序。还有更多 PHP 无法控制的故障点可能导致电子邮件无法发送。因此,FALSE
将帮助您指明正确的方向,而 TRUE
并不一定意味着您的电子邮件已成功发送。值得注意的是!
许多共享网络主机,尤其是免费网络主机提供商,要么不允许从其服务器发送电子邮件,要么限制在任何给定时间段内可以发送的数量。这是因为他们努力限制垃圾邮件发送者利用其更便宜的服务。
如果您认为您的主机有电子邮件限制或阻止发送电子邮件,请查看他们的常见问题解答,看看他们是否列出了任何此类限制。否则,您可能需要联系他们的支持人员,以验证发送电子邮件是否存在任何限制。
通常,由于各种原因,通过 PHP(和其他服务器端编程语言)发送的电子邮件最终会进入收件人的垃圾邮件文件夹。在对代码进行故障排除之前,请务必检查那里。
为了避免通过 PHP 发送的邮件被发送到收件人的垃圾邮件文件夹,您可以在 PHP 代码中或其他方面执行多种操作,以最大程度地减少电子邮件被标记为垃圾邮件的机会。 Michiel de Mare 提供的好建议包括:
有关此主题的详细信息,请参阅如何确保以编程方式发送的电子邮件不会自动标记为垃圾邮件?。
如果邮件缺少“发件人”和“回复”等通用标头,某些垃圾邮件软件将拒绝邮件:
$headers = array("From: from@example.com", "Reply-To: replyto@example.com", "X-Mailer: PHP/" . PHP_VERSION ); $headers = implode("\r\n", $headers); mail($to, $subject, $message, $headers);
无效的标头与没有标头一样糟糕。一个不正确的字符就可能使您的电子邮件脱轨。请仔细检查以确保您的语法正确,因为 PHP 不会为您捕获这些错误。
$headers = array("From from@example.com", // missing colon "Reply To: replyto@example.com", // missing hyphen "X-Mailer: "PHP"/" . PHP_VERSION // bad quotes );
发件人:
发件人虽然邮件必须有发件人:发件人,但您不能只使用任何值。特别是用户提供的发件人地址是阻止邮件的可靠方法:
$headers = array("From: $_POST[contactform_sender_email]"); // No!
原因:您的网络或发送邮件服务器未列入 SPF/DKIM 白名单,无法假装对 @hotmail 或 @gmail 地址负责。它甚至可能会默默地丢弃未配置的 From:
发件人域的邮件。
有时,问题就像电子邮件收件人的值不正确一样简单。这可能是由于使用了不正确的变量。
$to = 'user@example.com'; // other variables .... mail($recipient, $subject, $message, $headers); // $recipient should be $to
测试此问题的另一种方法是将收件人值硬编码到 mail()
函数调用中:
mail('user@example.com', $subject, $message, $headers);
这可以应用于所有 mail()
参数。
为了帮助排除电子邮件帐户问题,请将您的电子邮件发送到不同电子邮件提供商的多个电子邮件帐户。。如果您的电子邮件未到达用户的 Gmail 帐户,请将相同的电子邮件发送到 Yahoo 帐户、Hotmail 帐户和常规 POP3 帐户(例如您的 ISP 提供的电子邮件帐户)。
如果电子邮件到达所有或部分其他电子邮件帐户,则您知道您的代码正在发送电子邮件,但电子邮件帐户提供商可能出于某种原因阻止了它们。如果电子邮件未到达任何电子邮件帐户,则问题很可能与您的代码有关。
如果您已将表单方法设置为 POST
,请确保使用 $_POST
查找表单值。如果您已将其设置为 GET
或根本没有设置,请确保使用 $_GET
查找表单值。
action
值指向正确的位置确保您的表单 action
属性包含指向您的 PHP 邮件代码的值。