<?php
    $name = $_POST['name'];
    $email = $_POST['email'];
    $message = $_POST['message'];
    $from = 'From: yoursite.com';
    $to = 'contact@yoursite.com';
    $subject = 'Customer Inquiry';
    $body = "From: $name\n E-Mail: $email\n 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>';
        }
    }
?>

我试着创建了一个简单的邮件表单。表单本身在我的index.html页面上,但它提交到一个单独的“感谢您的提交”页面thanks . PHP,其中嵌入了上述PHP代码。 代码完美地提交,但从未发送电子邮件。我该如何解决这个问题?


当前回答

你可以使用PHPMailer,它工作得很完美,这里有一个代码示例:

<?php
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;

require 'vendor/phpmailer/phpmailer/src/Exception.php';
require 'vendor/phpmailer/phpmailer/src/PHPMailer.php';
require 'vendor/phpmailer/phpmailer/src/SMTP.php';
$editor = $_POST["editor"];
$subject = $_POST["subject"];
$to = $_POST["to"];

try {

    if ($_SERVER["REQUEST_METHOD"] == "POST") {

        $mail = new PHPMailer();
        $mail->IsSMTP();
        $mail->Mailer = "smtp";
        $mail->SMTPDebug  = 1;
        $mail->SMTPAuth   = TRUE;
        $mail->SMTPSecure = "tls";
        $mail->Port       = 587;
        $mail->Host       = "smtp.gmail.com";//using smtp server
        $mail->Username   = "XXXXXXXXXX@gmail.com";//the email which will send the email 
        $mail->Password   = "XXXXXXXXXX";//the password

        $mail->IsHTML(true);
        $mail->AddAddress($to, "recipient-name");
        $mail->SetFrom("XXXXXXXXXX@gmail.com", "from-name");
        $mail->AddReplyTo("XXXXXXXXXX@gmail.com", "reply-to-name");
        $mail->Subject = $subject;
        $mail->MsgHTML($editor);




        if (!$mail->Send()) {
            echo "Error while sending Email.";
            var_dump($mail);
        } else {
            echo "Email sent successfully";
        }
    }
} catch (Exception $e) {
    echo $e->getMessage();
}

其他回答

$name = $_POST['name'];
$email = $_POST['email'];
$reciver = '/* Reciver Email address */';
if (filter_var($reciver, FILTER_VALIDATE_EMAIL)) {
    $subject = $name;
    // To send HTML mail, the Content-type header must be set.
    $headers = 'MIME-Version: 1.0' . "\r\n";
    $headers .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n";
    $headers .= 'From:' . $email. "\r\n"; // Sender's Email
    //$headers .= 'Cc:' . $email. "\r\n"; // Carbon copy to Sender
    $template = '<div style="padding:50px; color:white;">Hello ,<br/>'
        . '<br/><br/>'
        . 'Name:' .$name.'<br/>'
        . 'Email:' .$email.'<br/>'
        . '<br/>'
        . '</div>';
    $sendmessage = "<div style=\"background-color:#7E7E7E; color:white;\">" . $template . "</div>";
    // Message lines should not exceed 70 characters (PHP rule), so wrap it.
    $sendmessage = wordwrap($sendmessage, 70);
    // Send mail by PHP Mail Function.
    mail($reciver, $subject, $sendmessage, $headers);
    echo "Your Query has been received, We will contact you soon.";
} else {
    echo "<span>* invalid email *</span>";
}

虽然这个答案的某些部分仅适用于mail()函数本身的使用,但这些故障排除步骤中的许多都可以应用于任何PHP邮件系统。

脚本不发送电子邮件的原因有很多。除非存在明显的语法错误,否则很难诊断这些问题。如果没有,您需要运行下面的检查表,以找到您可能遇到的任何潜在陷阱。

确保启用了错误报告,并设置为报告所有错误

错误报告对于消除代码中的错误和PHP遇到的一般错误是必不可少的。需要启用错误报告以接收这些错误。将以下代码放在PHP文件的顶部(或主配置文件中)将启用错误报告。

error_reporting(-1);
ini_set('display_errors', 'On');
set_error_handler("var_dump");

参见如何在PHP中获得有用的错误消息?-这是关于这方面更多细节的答案。

确保调用了mail()函数

这可能看起来很愚蠢,但一个常见的错误是忘记在代码中实际放置mail()函数。确保它在那里,没有被注释掉。

确保正确地调用了mail()函数

字符串$to,字符串$subject,字符串$message[,字符串$additional_headers[,字符串$additional_parameters]])

邮件函数接受三个必需的参数,还可以选择第四个和第五个参数。如果对mail()的调用没有至少三个参数,则会失败。

如果对mail()的调用没有正确顺序的正确参数,它也会失败。

检查服务器的邮件日志

你的网络服务器应该记录所有通过它发送电子邮件的尝试。这些日志的位置会有所不同(您可能需要询问服务器管理员它们的位置),但通常可以在日志下的用户根目录中找到它们。其中将是服务器报告的错误消息,如果有的话,与您尝试发送电子邮件有关。

检查端口连接失败

Port block is a very common problem that most developers face while integrating their code to deliver emails using SMTP. And, this can be easily traced at the server maillogs (the location of the server of mail log can vary from server to server, as explained above). In case you are on a shared hosting server, ports 25 and 587 remain blocked by default. This block is been purposely done by your hosting provider. This is true even for some of the dedicated servers. When these ports are blocked, try to connect using port 2525. If you find that the port is also blocked, then the only solution is to contact your hosting provider to unblock these ports.

大多数主机提供商阻止这些电子邮件端口,以保护他们的网络免受任何垃圾邮件的发送。

使用端口25或587作为普通/TLS连接,端口465用于SSL连接。对于大多数用户,建议使用端口587,以避免某些主机提供商设置的速率限制。

不要使用错误抑制操作符

在PHP中,当错误抑制操作符@被添加到表达式前时,该表达式可能生成的任何错误消息都将被忽略。在某些情况下,使用这个操作符是必要的,但发送邮件不是其中之一。

如果您的代码包含@mail(…),那么您可能隐藏了有助于调试的重要错误消息。删除@并查看是否报告任何错误。

只有在随后使用error_get_last()检查具体失败时才可取。

检查mail()返回值

mail()函数:

如果邮件已成功接受交付,则返回TRUE,否则返回FALSE。重要的是要注意,仅仅因为邮件被接受交付,并不意味着邮件将实际到达预定目的地。

这一点很重要,因为:

If you receive a FALSE return value you know the error lies with your server accepting your mail. This probably isn't a coding issue but a server configuration issue. You need to speak to your system administrator to find out why this is happening. If you receive a TRUE return value it does not mean your email will definitely be sent. It just means the email was sent to its respective handler on the server successfully by PHP. There are still more points of failure outside of PHP's control that can cause the email to not be sent.

因此,FALSE将帮助您指出正确的方向,而TRUE并不一定意味着您的电子邮件发送成功。这一点很重要!

确保您的托管提供商允许您发送电子邮件,而不限制邮件发送

许多共享网络主机,尤其是免费的网络主机提供商,要么不允许从他们的服务器发送电子邮件,要么限制在任何给定的时间内可以发送的电子邮件数量。这是由于他们努力限制垃圾邮件发送者利用他们的廉价服务。

如果你认为你的主机有电子邮件限制或阻止发送电子邮件,检查他们的常见问题,看看他们是否列出了任何这样的限制。否则,你可能需要联系他们的支持,以核实是否有关于发送电子邮件的任何限制。

检查垃圾邮件文件夹;防止电子邮件被标记为垃圾邮件

通常,由于各种原因,通过PHP(和其他服务器端编程语言)发送的电子邮件最终会出现在收件人的垃圾邮件文件夹中。在对代码进行故障排除之前,一定要检查该位置。

为了避免通过PHP发送的邮件被发送到收件人的垃圾邮件文件夹,可以在PHP代码和其他代码中进行各种操作,以最大限度地减少电子邮件被标记为垃圾邮件的可能性。来自Michiel de Mare的建议包括:

Use email authentication methods, such as SPF, and DKIM to prove that your emails and your domain name belong together, and to prevent spoofing of your domain name. The SPF website includes a wizard to generate the DNS information for your site. Check your reverse DNS to make sure the IP address of your mail server points to the domain name that you use for sending mail. Make sure that the IP-address that you're using is not on a blacklist Make sure that the reply-to address is a valid, existing address. Use the full, real name of the addressee in the To field, not just the email-address (e.g. "John Smith" <john@blacksmiths-international.com> ). Monitor your abuse accounts, such as abuse@yourdomain.example and postmaster@yourdomain.example. That means - make sure that these accounts exist, read what's sent to them, and act on complaints. Finally, make it really easy to unsubscribe. Otherwise, your users will unsubscribe by pressing the spam button, and that will affect your reputation.

参见如何确保以编程方式发送的电子邮件不会被自动标记为垃圾邮件?有关此主题的更多信息。

确保提供了所有的邮件标题

一些垃圾邮件软件如果缺少常见的标题,如“发件人”和“回复收件人”,就会拒绝邮件:

$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: sender

虽然邮件必须有一个From: sender,但您不能只使用任何值。特别是用户提供的发件人地址是一种确保邮件被拦截的方法:

$headers = array("From: $_POST[contactform_sender_email]"); // No!

原因:你的网络或发送邮件的服务器没有被SPF/ dkim白名单来假装对@hotmail或@gmail地址负责。它甚至可以使用未配置的发件人域静默地丢弃邮件。

确保收件人值是正确的

有时,问题很简单,只是电子邮件收件人的值不正确。这可能是由于使用了不正确的变量。

$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来查找表单值。

确保您的表单操作值指向正确的位置

确保表单操作属性包含指向PHP邮件代码的值。

<form action="send_email.php" method="POST">

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

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

给他们的技术支持发一封电子邮件(在他们的在线支持或常见问题解答之后)应该说明你的服务器上是否有电子邮件功能。

确保配置了本地主机邮件服务器

如果您正在使用WAMP、MAMP或XAMPP在本地工作站上开发,那么您的工作站上可能没有安装电子邮件服务器。如果没有,PHP默认情况下不能发送邮件。

您可以通过安装一个基本的邮件服务器来解决这个问题。对于Windows系统,你可以使用免费的水星邮件。

你也可以使用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/web服务器设置。通常情况下,您将邮件探测发送到:他们的地址,然后获得交付报告和更具体的故障或分析:

mail-tester。例子(免费/简单) glockapps.com(免费/ $ $ $) senforensics.com(注册/ $ $ $) mailtrap。io (pro / $ $ $) ultrtools /…/emailTest(免费/MX检查) 不同:http://www.verticalresponse.com/blog/7-email-testing-delivery-tools/

使用不同的邮件

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

最受欢迎的是:PHPMailer 同样有特色的还有SwiftMailer 甚至是更老的PEAR::Mail。

所有这些都可以与专业的SMTP服务器/服务提供商相结合。(因为当涉及到电子邮件设置/配置时,典型的08/15共享虚拟主机计划是随机的。)

我有这个问题,并发现剥离标题帮助我获得邮件。 所以这个:

$headers  = "MIME-Version: 1.0;\r\n";
$headers .= "Content-type: text/plain; charset=utf-8;\r\n";
$headers .= "To: ".$recipient."\r\n";
$headers .= "From: ".__SITE_TITLE."\r\n";
$headers .= "Reply-To: ".$sender."\r\n";

成为这个:

$headers = "From: ".__SITE_TITLE."\r\n";
$headers .= "Reply-To: ".$sender."\r\n";

不需要To:标头。

邮件客户端非常擅长嗅出url并将其重写为超链接。所以我不需要编写HTML并在content-type头文件中指定text/ HTML。我只是在消息体中添加了带\r\n的新行。 我知道这不是编码纯粹主义者的方法,但它适用于我所需要的。

把这两件事分开和一起尝试:

删除if($_POST['submit']){} 移除$from(只是我的直觉)

总是尝试在邮件函数中发送标题。 如果您通过localhost发送邮件,则执行SMTP设置以发送邮件。 如果您通过服务器发送邮件,请检查您的服务器上是否启用了电子邮件发送功能。