搜索

首页  >  问答  >  正文

PHP邮件函数未能完全发送电子邮件

<p><pre class="brush:php;toolbar:false;"><?php $name = $_POST['name']; $email = $_POST['email']; $message = $_POST['message']; $from = 'From: yoursite.com'; $to = 'contact@yoursite.com'; $subject = 'Customer Inquiry'; $body = "From: $namen E-Mail: $emailn Message:n $message"; if ($_POST['submit']) { if (mail ($to, $subject, $body, $from)) { echo '<p>Your message has been sent!</p>'; } else { echo '<p>Something went wrong, go back and try again!</p>'; } } ?></pre> <p>我尝试创建一个简单的邮件表单。表单本身位于我的 <code>index.html</code> 页面上,但它提交到一个单独的“感谢您的提交”页面 <code>thankyou.php</code>,其中嵌入了上述 PHP 代码。 代码完美提交,但从未发送电子邮件。我该如何解决这个问题?</p>
P粉322106755P粉322106755454 天前524

全部回复(1)我来回复

  • P粉742550377

    P粉7425503772023-08-28 09:20:20

    尽管此答案的某些部分仅适用于 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 邮件代码的值。

    确保网络主机支持发送电子邮件

    某些网络托管提供商不允许或启用通过其服务器发送电子邮件。造成这种情况的原因可能有所不同,但如果他们禁止发送邮件,您将需要使用替代方法,即使用第三方为您发送这些电子邮件。

    发送给他们的技术支持的电子邮件(在访问他们的在线支持或常见问题解答之后)应该澄清您的服务器上是否可以使用电子邮件功能。

    确保已配置 localhost 邮件服务器

    如果您使用 WAMP、MAMP 或 XAMPP 在本地工作站上进行开发,则您的工作站上可能未安装电子邮件服务器。如果没有,PHP 默认无法发送邮件。

    您可以通过安装基本的邮件服务器来克服这个问题。对于 Windows,您可以使用免费的 Mercury Mail

    您还可以使用 SMTP 发送电子邮件。请参阅来自 这个很棒的答案 >Vikas 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/网络服务器设置。通常,您将邮件探测发送到:他们的地址,然后获取递送报告和更具体的故障或稍后分析:

    使用不同的邮件程序

    PHP 的内置 mail() 函数很方便,通常可以完成工作,但它 有其缺点。幸运的是,有一些替代方案可以提供更强大的功能和灵活性,包括处理上述许多问题:

    所有这些都可以与专业的 SMTP 服务器/服务提供商结合使用。 (因为典型的 08/15 共享虚拟主机计划在电子邮件设置/可配置性方面时好时坏。)

    回复
    0
  • 取消回复