虽然这个答案的某些部分仅适用于mail()函数本身的使用,但许多故障排除步骤都可以应用于任何PHP邮件系统。
您的脚本似乎没有发送电子邮件的原因有多种。除非有明显的语法错误,否则很难诊断这些事情。如果没有,您需要查看下面的清单,找出您可能遇到的任何潜在陷阱。
确保启用错误报告并将其设置为报告所有错误
错误报告对于根除代码中的错误和PHP遇到的常规错误至关重要。需要启用错误报告才能接收这些错误。将以下代码放在PHP文件的顶部(或主配置文件中)将启用错误报告。error_reporting(-1);ini_set('display_errors', 'On');set_error_handler("var_dump");
确保mail()调用该函数
它可能看起来很愚蠢,但常见的错误是忘记将mail()函数实际放在代码中。确保它在那里,没有注释掉。
确保mail()正确调用该函数bool mail(string $ to,string $ subject,string $ message [,string $ additional_headers [,string $ additional_parameters]])
邮件功能需要三个必需参数,可选择第四个和第五个参数。如果您的呼叫mail()至少没有三个参数,则会失败。
如果您的呼叫mail()没有正确顺序的正确参数,它也将失败。
检查服务器的邮件日志
您的Web服务器应记录所有通过它发送电子邮件的尝试。这些日志的位置会有所不同(您可能需要向服务器管理员询问它们所在的位置),但通常可以在用户的根目录下找到它们logs。内部将是服务器报告的错误消息(如果有),与您尝试发送电子邮件有关。
检查端口连接故障
端口块是一个非常常见的问题,大多数开发人员在整合其代码以使用SMTP传递电子邮件时会遇到这个问 并且,这可以在服务器maillogs上轻松跟踪(邮件日志服务器的位置因服务器而异,如上所述)。如果您在共享主机服务器上,默认情况下端口25和587仍然处于阻止状态。此块是由您的托管服务提供商专门完成的。即使对于某些专用服务器也是如此。当这些端口被阻止时,尝试使用端口2525进行连接。如果您发现该端口也被阻止,那么唯一的解决方案是联系您的托管服务提供商以取消阻止这些端口。
大多数托管服务提供商阻止这些电子邮件端口,以保护他们的网络不发送任何垃圾邮件。
端口25或587用于普通/ TLS连接,端口465用于SSL连接。对于大多数用户,建议使用端口587来避免某些主机提供商设置的速率限制。
不要使用错误抑制运算符
当错误抑制运算符 @被添加到PHP中的表达式之前,将忽略该表达式可能生成的任何错误消息。在某些情况下,使用此运算符是必要的,但发送邮件不是其中之一。
如果您的代码包含,@mail(...)那么您可能会隐藏重要的错误消息,这些消息将帮助您进行调试。删除@并查看是否报告任何错误。
检查mail()返回值TRUE如果邮件已成功接受传递,FALSE则返回,否则返回。重要的是要注意,仅仅因为邮件被接受传递,并不意味着邮件实际上将到达预定目的地。
这一点很重要,因为:如果您收到FALSE返回值,则表示错误在于您的服务器接受您的邮件。这可能不是编码问题,而是服务器配置问题。您需要与系统管理员联系,以了解发生这种情况的原因。
如果您收到TRUE返回值,则并不意味着您的电子邮件肯定会被发送。它只是意味着电子邮件已成功通过PHP发送到服务器上的各自处理程序。PHP控件之外还有更多的失败点可能导致电子邮件无法发送。
因此,FALSE有助于指出您正确的方向,TRUE但并不一定意味着您的电子邮件已成功发送。这一点很重要!
确保您的托管服务提供商允许您发送电子邮件,但不限制邮件发送
许多共享的虚拟主机,特别是免费的虚拟主机提供商,要么不允许从服务器发送电子邮件,要么限制在任何给定时间段内可以发送的数量。这是因为他们努力限制垃圾邮件发送者利用他们更便宜的服务。
如果您认为主持人有电子邮件限制或阻止发送电子邮件,请查看他们的常见问题解答,看看他们是否列出了任何此类限制。否则,您可能需要联系他们的支持,以验证是否有任何限制发送电子邮件。
检查垃圾邮件文件 防止电子邮件被标记为垃圾邮件
通常,由于各种原因,通过PHP(和其他服务器端编程语言)发送的电子邮件最终会出现在收件人的垃圾邮件文件夹中。在排除代码故障之前,请务必检查。
为了避免通过PHP发送的邮件被发送到收件人的垃圾邮件文件夹,您可以使用PHP代码和其他方式执行各种操作,以最大程度地降低电子邮件被标记为垃圾邮件的可能性。Michiel de Mare的好建议包括:使用电子邮件身份验证方法(如SPF和DKIM)来证明您的电子邮件和域名属于一起,并防止欺骗您的域名。SPF网站包含一个向您生成站点DNS信息的向导。
检查您的反向DNS,以确保您的邮件服务器指向的IP地址,您用于发送邮件的域名。
确保您使用的IP地址不在黑名单中
确保回复地址是有效的现有地址。
在“收件人”字段中使用收件人的完整真实姓名,而不仅仅是电子邮件地址(例如"John Smith" )。
监控您的滥用帐户,例如abuse@yourdomain.com和postmaster@yourdomain.com。这意味着 - 确保这些帐户存在,阅读发送给他们的内容,并根据投诉采取行动。
最后,让取消订阅真的很容易。否则,您的用户将通过按垃圾邮件按钮取消订阅,这将影响您的声誉。
确保提供所有邮件标头
如果邮件丢失了常见标题,例如“发件人”和“回复”,则某些垃圾邮件软件会拒绝邮件:$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);
不要使用虚假From:发件人
虽然邮件必须有发件人:发件人,但您可能不只是使用任何值。特别是用户提供的发件人地址是阻止邮件被阻止的绝对方式:$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邮件代码的值。
确保Web主机支持发送电子邮件
某些Web托管服务提供商不允许或启用通过其服务器发送电子邮件。原因可能有所不同,但如果他们禁止发送邮件,您将需要使用另一种方法,使用第三方为您发送这些电子邮件。
发送给他们的技术支持的电子邮件(在他们的在线支持或常见问题解答之后)应该澄清您的服务器上是否有电子邮件功能。
确保localhost已配置邮件服务器
如果使用WAMP,MAMP或XAMPP在本地工作站上进行开发,则可能未在工作站上安装电子邮件服务器。如果没有,PHP默认情况下无法发送邮件。
您可以通过安装基本邮件服务器来解决此问题。对于Windows,您可以使用免费的Mercury Mail。
您也可以使用SMTP发送电子邮件。见这个伟大的答案从维卡斯Dwivedi学习如何做到这一点。
启用PHP的自定义 mail.log
除了MTA和PHP的日志文件之外,您还可以专门为该mail()功能启用日志记录。它不记录完整的SMTP交互,但至少记录函数调用参数和调用脚本。ini_set("mail.log", "/tmp/mail.log");ini_set("mail.add_x_header", TRUE);
有关详细信息,请参见http://php.net/manual/en/mail.configuration.php。(最好在php.ini或者.user.ini或者.htaccess可能启用这些选项。)
查看邮件测试服务
您可以使用各种传递和垃圾邮件检查服务来测试您的MTA / Web服务器设置。通常,您将邮件探测发送到:他们的地址,然后获取发送报告以及更具体的故障或分析:
使用其他邮件程序
PHP的内置mail()功能非常方便,通常可以完成工作,但它有其缺点。幸运的是,有一些替代方案可提供更多功能和灵活性,包括处理上述许多问题:
所有这些都可以与专业的SMTP服务器/服务提供商结合使用。(因为在电子邮件设置/可配置性方面,典型的08/15共享虚拟主机计划会受到影响。)