PHP邮件功能没有完成电子邮件的发送答案

尽管此答案的某些部分仅适用于mail() 函数本身的使用,但其中许多故障排除步骤可以应用于任何 PHP 邮件系统。
您的脚本似乎没有发送电子邮件有多种原因。除非有明显的语法错误,否则很难诊断这些事情。如果没有,您需要通过下面的清单来查找您可能遇到的任何潜在陷阱。
确保启用错误报告并设置为报告所有错误
错误报告对于根除代码中的错误和 PHP 遇到的一般错误至关重要。需要启用错误报告才能接收这些错误。将以下代码放在 PHP 文件的顶部(或主配置文件中)将启用错误报告。
error_reporting(-1);ini_set(‘display_errors’, ‘On’);set_error_handler(“var_dump”);
有关更多详细信息,请参阅How can I get useful error messages in PHP? — this answer。
确保调用了 mail() 函数
这可能看起来很愚蠢,但一个常见的错误是忘记将mail() 函数实际放置在您的代码中。确保它在那里并且没有被注释掉。
确保正确调用 mail() 函数
布尔邮件(字符串 $to,字符串 $subject,字符串 $message [,字符串 $additional_headers [,字符串 $additional_parameters ]])
mail 函数接受三个必需的参数,以及可选的第四个和第五个参数。如果您对mail() 的调用没有至少三个参数,它将失败。
如果您对mail() 的调用没有正确顺序的正确参数,它也会失败。
检查服务器的邮件日志
您的 Web 服务器应该记录通过它发送电子邮件的所有尝试。这些日志的位置会有所不同(您可能需要询问服务器管理员它们的位置),但它们通常可以在logs 下的用户根目录中找到。内部将是服务器报告的与您尝试发送电子邮件相关的错误消息(如果有)。
检查端口连接失败
端口阻塞是大多数开发人员在集成他们的代码以使用 SMTP 传递电子邮件时面临的一个非常常见的问题。而且,这可以在服务器邮件日志中轻松跟踪(邮件日志服务器的位置可能因服务器而异,如上所述)。如果您在共享托管服务器上,则默认情况下端口 25 和 587 仍被阻止。此块是由您的托管服务提供商故意完成的。即使对于某些专用服务器也是如此。当这些端口被阻塞时,请尝试使用端口 2525 连接。如果您发现该端口也被阻塞,那么唯一的解决方案是联系您的托管服务提供商以解除这些端口的阻塞。
大多数托管服务提供商都会阻止这些电子邮件端口,以保护他们的网络不发送任何垃圾邮件。
使用端口 25 或 587 进行普通/TLS 连接,使用端口 465 进行 SSL 连接。对于大多数用户,建议使用端口 587 以避免某些托管服务提供商设置的速率限制。
不要使用错误抑制运算符
当 error suppression operator @ 被添加到 PHP 中的表达式之前,该表达式可能生成的任何错误消息都将被忽略。在某些情况下需要使用此运算符,但发送邮件是不是其中之一。
如果您的代码包含@mail(…),那么您可能隐藏了有助于调试的重要错误消息。去掉@,看看有没有报错。
仅当您在之后check with error_get_last() 出现具体故障时才建议这样做。
检查mail() 返回值
mail() 函数:
如果邮件被成功接收,则返回TRUE,否则返回FALSE。重要的是要注意,仅仅因为邮件被接受交付,并不意味着邮件实际上会到达预定目的地。
这一点很重要,因为:
如果您收到FALSE 返回值,您就知道错误在于您的服务器接受了您的邮件。这可能不是编码问题,而是服务器配置问题。您需要与您的系统管理员联系以了解发生这种情况的原因。如果您收到TRUE 返回值,这并不意味着您的电子邮件一定会被发送。这只是意味着电子邮件已通过 PHP 成功发送到服务器上的相应处理程序。还有更多的故障点超出了 PHP 的控制范围,可能导致电子邮件无法发送。
所以FALSE 将帮助您指出正确的方向,而TRUE 确实不是必然意味着您的电子邮件已成功发送。这一点很重要!
确保您的托管服务提供商允许您发送电子邮件并且不限制邮件发送
许多共享虚拟主机,尤其是免费虚拟主机提供商,要么不允许从其服务器发送电子邮件,要么限制在任何给定时间段内可以发送的数量。这是因为他们努力限制垃圾邮件发送者利用他们更便宜的服务。
如果您认为您的主机有电子邮件限制或阻止发送电子邮件,请查看他们的常见问题解答以查看他们是否列出了任何此类限制。否则,您可能需要联系他们的支持人员,以验证是否对发送电子邮件有任何限制。
检查垃圾邮件文件夹;防止电子邮件被标记为垃圾邮件
通常,由于各种原因,通过 PHP(和其他服务器端编程语言)发送的电子邮件最终会进入收件人的垃圾邮件文件夹。在对代码进行故障排除之前,请务必检查那里。
为避免通过 PHP 发送的邮件被发送到收件人的垃圾邮件文件夹,您可以在 PHP 代码中或其他方式中执行各种操作,以尽量减少您的电子邮件被标记为垃圾邮件的机会。来自Michiel de Mare 的好建议包括:
使用SPF、DKIM等邮箱认证方式来证明你的邮箱和你的域名是同一的,防止你的域名被冒用。 SPF 网站包含一个为您的站点生成 DNS 信息的向导。Check 您的reverse DNS 以确保您的邮件服务器的 IP 地址指向您用于发送邮件的域名。确保您使用的 IP 地址是 not on a blacklist确保回复地址是有效的现有地址。在“收件人”字段中使用收件人的完整真实姓名,而不仅仅是电子邮件地址(例如 “John Smith” <[email protected]> )。监控您的滥用帐户,例如[email protected] 和[email protected]。这意味着 – 确保这些帐户存在,阅读发送给他们的内容,并对投诉采取行动。最后,制作它真的很容易退订。否则,您的用户将按垃圾邮件按钮,这将影响您的声誉。
有关此主题的更多信息,请参阅How do you make sure email you send programmatically is not automatically marked as spam?。
确保提供所有邮件标题
如果邮件缺少常见的标头,例如“From”和“Reply-to”,一些垃圾邮件软件会拒绝邮件:
$headers = array(“From: [email protected]”, “Reply-To: [email protected]”, “X-Mailer: PHP/” . PHP_VERSION);$headers = implode(“rn”, $headers);mail($to, $subject, $message, $headers);确保邮件标头没有语法错误
无效的标头与没有标头一样糟糕。一个不正确的字符可能会导致您的电子邮件脱轨。仔细检查以确保您的语法是正确的,因为 PHP 将不是为您捕获这些错误。
$headers = array(“From [email protected]”, // missing colon “Reply To: [email protected]”, // missing hyphen “X-Mailer: “PHP”/” . PHP_VERSION // bad quotes);不要使用虚假的From: 发件人
虽然邮件必须有 From: 发件人,但您不能只使用任何价值。特别是用户提供的发件人地址是阻止邮件的可靠方法:
$headers = array(“From: $_POST[contactform_sender_email]”); // No!
原因:您的 Web 或发送邮件服务器未列入 SPF/DKIM 白名单以假装负责@hotmail 或@gmail 地址。它甚至可以静默丢弃带有未配置的From: 发件人域的邮件。
确保收件人值正确
有时问题就像电子邮件收件人的值不正确一样简单。这可能是由于使用了不正确的变量。
$to = ‘[email protected]’;// other variables ….mail($recipient, $subject, $message, $headers); // $recipient should be $to
另一种测试方法是将接收者值硬编码到mail() 函数调用中:
mail(‘[email protected]’, $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 发送电子邮件。请参阅Vikas Dwivedi 中的this great answer 以了解如何执行此操作。
启用PHP的自定义mail.log
除了您的 MTA 和 PHP 的日志文件之外,您还可以专门启用 logging for the mail() function。它没有记录完整的 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/网络服务器设置。通常,您将邮件探测发送到:他们的地址,然后获取交付报告和更具体的失败或分析:
mail-tester.example(免费/简单)glockapps.com(免费/$$$)senforensics.com(注册/$$$)mailtrap.io(专业/$$$)ultratools/…/emailTest(仅限免费/MX 检查)各种:http://www.verticalresponse.com/blog/7-email-testing-delivery-tools/使用不同的邮件程序
PHP 的内置 mail() 函数很方便,通常可以完成工作,但它 has its shortcomings。幸运的是,有一些替代方案可以提供更多的功能和灵活性,包括处理上述许多问题:
最受欢迎的是:PHPMailer同样功能:SwiftMailer甚至是较旧的PEAR::Mail。
所有这些都可以与专业的 SMTP 服务器/服务提供商结合使用。 (因为在电子邮件设置/配置方面,典型的 08/15 共享虚拟主机计划会受到影响。)