PHP邮件功能无法完成电子邮件的发送

本文翻译自:PHP mail function doesn't complete sending of e-mail

<?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>';
        }
    }
?>

I've tried creating a simple mail form. 我尝试创建一个简单的邮件表单。 The form itself is on my index.html page, but it submits to a separate "thank you for your submission" page, thankyou.php , where the above PHP code is embedded. 表单本身在我的index.html页面上,但是它提交到单独的“感谢您提交”页面, thankyou.php ,上面的PHP代码嵌入其中。 The code submits perfectly, but never sends an email. 该代码可以完美提交,但从不发送电子邮件。 How can I fix this? 我怎样才能解决这个问题?


#1楼

参考:https://stackoom.com/question/1fP8u/PHP邮件功能无法完成电子邮件的发送


#2楼

Although there are portions of this answer that apply to only to the usage of the mail() function itself, many of these troubleshooting steps can be applied to any PHP mailing system. 尽管此答案的某些部分仅适用于使用mail()函数本身,但是许多故障排除步骤都可以应用于任何PHP邮件系统。

There are a variety of reasons your script appears to not be sending emails. 有多种原因导致您的脚本似乎不发送电子邮件。 It's difficult to diagnose these things unless there is an obvious syntax error. 除非存在明显的语法错误,否则很难诊断这些问题。 Without one you need to run through the checklist below to find any potential pitfalls you may be encountering. 如果没有,您需要仔细阅读以下清单,以查找您可能遇到的潜在陷阱。

Make sure error reporting is enabled and set to report all errors 确保已启用错误报告并设置为报告所有错误

Error reporting is essential to rooting out bugs in your code and general errors that PHP encounters. 错误报告对于根除代码中的错误以及PHP遇到的一般错误至关重要。 Error reporting needs to be enabled to receive these errors. 需要启用错误报告以接收这些错误。 Placing the following code at the top of your PHP files (or in a master configuration file) will enable error reporting. 将以下代码放在PHP文件的顶部(或主配置文件中)将启用错误报告。

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

See this Stack Overflow answer for more details on this. 有关更多详细信息,请参见此堆栈溢出答案

Make sure the mail() function is called 确保已调用mail()函数

It may seem silly but a common error is to forget to actually place the mail() function in your code. 看起来很愚蠢,但是一个常见的错误是忘记将mail()函数实际放在代码中。 Make sure it is there and not commented out. 确保它在那里并且没有被注释掉。

Make sure the mail() function is called correctly 确保正确调用了mail()函数

bool mail ( string $to , string $subject , string $message [, string $additional_headers [, string $additional_parameters ]] ) 布尔邮件(字符串$ to,字符串$ subject,字符串$ message [,字符串$ additional_headers [,字符串$ additional_parameters]])

The mail function takes three required parameters and optionally a fourth and fifth one. 邮件功能需要三个必需的参数,还可以选择第四个和第五个参数。 If your call to mail() does not have at least three parameters it will fail. 如果您对mail()调用没有至少三个参数,它将失败。

If your call to mail() does not have the correct parameters in the correct order it will also fail. 如果您对mail()调用没有正确顺序的正确参数,则也会失败。

Check the server's mail logs 检查服务器的邮件日志

Your web server should be logging all attempts to send emails through it. 您的Web服务器应该记录所有通过它发送电子邮件的尝试。 The location of these logs will vary (you may need to ask your server administrator where they are located) but they can commonly be found in a user's root directory under logs . 这些日志的位置会有所不同(您可能需要询问服务器管理员,它们位于何处),但通常可以在用户根目录下的logs下找到它们。 Inside will be error messages the server reported, if any, related to your attempts to send emails. 服务器中报告的错误消息(如果有)与您发送电子邮件的尝试有关。

Check for Port connection failure 检查端口连接失败

Port block is a very common problem which most developers face while integrating their code to deliver emails using SMTP. 端口阻塞是大多数开发人员在集成其代码以使用SMTP传递电子邮件时面临的一个非常普遍的问题。 And, this can be easily traced at the server maillogs (the location of server of mail log can vary from server to server, as explained above). 并且,可以轻松地在服务器邮件日志中找到该邮件(如上所述,邮件日志的服务器位置可能因服务器而异)。 In case you are on a shared hosting server, the ports 25 and 587 remain blocked by default. 如果您在共享主机服务器上,则默认情况下端口25和587仍处于阻止状态。 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 port is also blocked, then the only solution is to contact your hosting provider to unblock these ports. 当这些端口被阻止时,请尝试使用端口2525进行连接。如果您发现该端口也被阻止,则唯一的解决方案是与主机提供商联系以解除对这些端口的阻止。

Most of the hosting providers block these email ports to protect their network from sending any spam emails. 大多数托管服务提供商会阻止这些电子邮件端口,以保护其网络免于发送垃圾邮件。

Use ports 25 or 587 for plain/TLS connections and port 465 for SSL connections. 将端口25或587用于纯/ TLS连接,将端口465用于SSL连接。 For most users, it is suggested to use port 587 to avoid rate limits set by some hosting providers. 对于大多数用户,建议使用端口587以避免某些托管服务提供商设置的速率限制。

Don't use the error suppression operator 不要使用错误抑制运算符

When the error suppression operator @ is prepended to an expression in PHP, any error messages that might be generated by that expression will be ignored. 错误抑制运算符 @前缀在PHP中的表达式中时,该表达式可能生成的任何错误消息都将被忽略。 There are circumstances where using this operator is necessary but sending mail is not one of them. 在某些情况下,必须使用此运算符,但发送邮件不是其中一种。

If your code contains @mail(...) then you may be hiding important error messages that will help you debug this. 如果您的代码包含@mail(...)则可能隐藏了重要的错误消息,这些消息将帮助您进行调试。 Remove the @ and see if any errors are reported. 删除@然后查看是否报告了任何错误。

It's only advisable when you check with error_get_last() right afterwards for concrete failures. 仅在之后立即使用error_get_last()检查具体故障时,才建议这样做。

Check the mail() return value 检查mail()返回值

The mail() function: mail()函数:

Returns TRUE if the mail was successfully accepted for delivery, FALSE otherwise. 如果邮件已成功接受传递,则返回TRUE ,否则返回FALSE It is important to note that just because the mail was accepted for delivery, it does NOT mean the mail will actually reach the intended destination. 重要的是要注意,仅仅因为邮件已被接受送达,并不意味着邮件实际上将到达预期的目的地。

This is important to note because: 注意这一点很重要,因为:

  • If you receive a FALSE return value you know the error lies with your server accepting your mail. 如果收到FALSE返回值,则表明错误在于服务器接受您的邮件。 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 your receive a TRUE return value it does not mean your email will definitely be sent. 如果您收到的返回值为TRUE ,则并不意味着一定会发送您的电子邮件。 It just means the email was sent to its respective handler on the server successfully by PHP. 这只是意味着电子邮件已通过PHP成功发送到服务器上的相应处理程序。 There are still more points of failure outside of PHP's control that can cause the email to not be sent. 在PHP的控制范围之外,还有更多故障点可能导致电子邮件无法发送。

So FALSE will help point you in the right direction whereas TRUE does not necessarily mean your email was sent successfully. 所以FALSE将帮助一点,你在正确的方向,而TRUE 并不一定意味着你的电子邮件成功发送。 This is important to note! 重要的是要注意!

Make sure your hosting provider allows you to send emails and does not limit mail sending 确保您的托管服务提供商允许您发送电子邮件,并且不限制邮件发送

Many shared webhosts, especially free webhosting providers, either do not allow emails to be sent from their servers or limit the amount that can be sent during any given time period. 许多共享的虚拟主机,尤其是免费的虚拟主机提供商,要么不允许从其服务器发送电子邮件,要么限制在任何给定时间段内可以发送的电子邮件数量。 This is due to their efforts to limit spammers from taking advantage of their cheaper services. 这是由于他们努力限制垃圾邮件发送者利用其便宜的服务。

If you think your host has emailing limits or blocks the sending of emails, check their FAQs to see if they list any such limitations. 如果您认为主机有电子邮件限制或阻止发送电子邮件,请查看其常见问题解答以查看是否列出了任何此类限制。 Otherwise, you may need to reach out to their support to verify if there are any restrictions in place around the sending of emails. 否则,您可能需要寻求他们的支持,以验证电子邮件发送周围是否存在任何限制。

Check spam folders; 检查垃圾邮件文件夹; prevent emails from being flagged as spam 防止将电子邮件标记为垃圾邮件

Oftentimes, for various reasons, emails sent through PHP (and other server-side programming languages) end up in a recipient's spam folder. 通常,由于各种原因,通过PHP(和其他服务器端编程语言)发送的电子邮件最终会位于收件人的垃圾邮件文件夹中。 Always check there before troubleshooting your code. 在对代码进行故障排除之前,请务必在此处进行检查。

To avoid mail sent through PHP from being sent to a recipient's spam folder, there are various things you can do, both in your PHP code and otherwise, to minimize the chances your emails are marked as spam. 为避免通过PHP发送的邮件被发送到收件人的垃圾邮件文件夹,您可以在PHP代码中以及其他方式中进行多种操作,以最大程度地减少将电子邮件标记为垃圾邮件的机会。 Good tips from Michiel de Mare include: 来自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. 使用SPFDKIM之类的电子邮件身份验证方法来证明您的电子邮件和域名属于同一类,并防止欺骗您的域名。 The SPF website includes a wizard to generate the DNS information for your site. SPF网站包括一个向导,用于为您的站点生成DNS信息。
  • 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. 检查 反向DNS ,以确保邮件服务器的IP地址指向用于发送邮件的域名。
  • Make sure that the IP-address that you're using is not on a blacklist 确保您使用的IP地址不在黑名单中
  • 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 (eg "John Smith" <john@blacksmiths-international.com> ). 在“收件人”字段中使用收件人的真实姓名,而不仅仅是电子邮件地址(例如"John Smith" <john@blacksmiths-international.com> )。
  • Monitor your abuse accounts, such as abuse@yourdomain.com and postmaster@yourdomain.com. 监视您的滥用帐户,例如abuse@yourdomain.com和postmaster@yourdomain.com。 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. 否则,您的用户将通过按垃圾邮件按钮退订,这将影响您的声誉。

See How do you make sure email you send programmatically is not automatically marked as spam? 请参阅如何确保以编程方式发送的电子邮件不会自动标记为垃圾邮件? for more on this topic. 有关此主题的更多信息。

Make sure all mail headers are supplied 确保提供了所有邮件头

Some spam software will reject mail if it is missing common headers such as "From" and "Reply-to": 如果某些垃圾邮件软件缺少常见的标头(例如“发件人”和“答复至”),它们将拒绝邮件:

$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);

Make sure mail headers have no syntax errors 确保邮件标题没有语法错误

Invalid headers are just as bad as having no headers. 无效的标题与没有标题一样糟糕。 One incorrect character could be all it takes to derail your email. 一个错误的字符可能就是使您的电子邮件出轨的全部方法。 Double-check to make sure your syntax is correct as PHP will not catch these errors for you. 仔细检查以确保语法正确,因为PHP 不会为您捕获这些错误。

$headers = array("From from@example.com", // missing colon
    "Reply To: replyto@example.com",      // missing hyphen
    "X-Mailer: "PHP"/" . PHP_VERSION      // bad quotes
);

Don't use a faux From: sender 不要使用伪造的From:发件人

While the mail must have a From: sender, you may not just use any value. 尽管邮件必须具有“发件人:”发件人,但您不能仅使用任何值。 In particular user-spplied sender addresses are a surefire way to get mails blocked: 特别是用户拼写的发件人地址是一种阻止邮件的可靠方法:

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

Reason: your web or sending mail server is not SPF/DKIM-whitelisted to pretend being responsible for @hotmail or @gmail addresses. 原因:您的Web或发送邮件服务器未列入SPF / DKIM白名单,以假装负责@hotmail或@gmail地址。 It may even silently drop mails with From: sender domains it's not configured for. 它甚至可以自动删除邮件与From:它没有配置为发件人域。

Make sure the recipient value is correct 确保收件人值正确

Sometimes the problem is as simple as having an incorrect value for the recipient of the email. 有时问题很简单,例如为电子邮件的接收者提供不正确的值。 This can be due to using an incorrect variable. 这可能是由于使用了错误的变量所致。

$to = 'user@example.com';
// other variables ....
mail($recipient, $subject, $message, $headers); // $recipient should be $to

Another way to test this is to hard code the recipient value into the mail() function call: 另一种测试方法是将收件人值硬编码到mail()函数调用中:

mail('user@example.com', $subject, $message, $headers); 

This can apply to all of the mail() parameters. 这可以应用于所有mail()参数。

Send to multiple accounts 发送到多个帐户

To help rule out email account issues, send your email to multiple email accounts at different email providers . 为了帮助排除电子邮件帐户问题,请将您的电子邮件发送到位于不同电子邮件提供商的多个电子邮件帐户。 If your emails are not arriving at a user's Gmail account, send the same emails to a Yahoo account, a Hotmail account, and a regular POP3 account (like your ISP-provided email account). 如果您的电子邮件没有到达用户的Gmail帐户,请将相同的电子邮件发送到Yahoo帐户,Hotmail帐户和常规POP3帐户(例如ISP提供的电子邮件帐户)。

If the emails arrive at all or some of the other email accounts, you know your code is sending emails but it is likely that the email account provider is blocking them for some reason. 如果电子邮件到达所有或其他一些电子邮件帐户,则您知道您的代码正在发送电子邮件,但是电子邮件帐户提供商可能出于某种原因阻止了它们。 If the email does not arrive at any email account, the problem is more likely to be related to your code. 如果电子邮件没有到达任何电子邮件帐户,则问题很可能与您的代码有关。

Make sure the code matches the form method 确保代码与form方法匹配

If you have set your form method to POST , make sure you are using $_POST to look for your form values. 如果将表单方法设置为POST ,请确保使用$_POST查找表单值。 If you have set it to GET or didn't set it at all, make sure you using $_GET to look for your form values. 如果已将其设置为GET或根本没有设置,请确保使用$_GET查找表单值。

Make sure your form action value points to the correct location 确保您的表单action值指向正确的位置

Make sure your form action attribute contains a value that points to your PHP mailing code. 确保您的表单action属性包含一个指向您的PHP邮件代码的值。

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

Make sure the Web host supports sending email 确保Web主机支持发送电子邮件

Some Web hosting providers do not allow or enable the sending of emails through their servers. 一些Web托管提供商不允许或启用通过其服务器发送电子邮件。 The reasons for this may vary but if they have disabled the sending of mail you will need to use an alternative method that uses a third party to send those emails for you. 造成这种情况的原因可能有所不同,但是如果他们禁用了邮件发送功能,则需要使用另一种方法,该方法使用第三方来为您发送这些电子邮件。

An email to their technical support (after a trip to their online support or FAQ) should clarify if email capabilities are available on your server. 给他们的技术支持的电子邮件(在访问他们的在线支持或FAQ之后)应阐明您的服务器上是否有电子邮件功能。

Make sure the localhost mail server is configured 确保已配置localhost邮件服务器

If you are developing on your local workstation using WAMP, MAMP, or XAMPP, an email server is probably not installed on your workstation. 如果使用WAMP,MAMP或XAMPP在本地工作站上进行开发,则工作站上可能未安装电子邮件服务器。 Without one, PHP cannot send mail by default. 没有一个,默认情况下PHP无法发送邮件。

You can overcome this by installing a basic mail server. 您可以通过安装基本邮件服务器来克服此问题。 For Windows you can use the free Mercury Mail . 对于Windows,您可以使用免费的Mercury Mail

You can also use SMTP to send your emails. 您还可以使用SMTP发送电子邮件。 See this great answer from Vikas Dwivedi to learn how to do this. 请查看Vikas Dwivedi的 出色答案 ,以了解如何执行此操作。

Enable PHP's custom mail.log 启用PHP的自定义mail.log

In addition to your MTA's and PHP's log file, you can enable logging for the mail() function specifically. 除了您的MTA和PHP的日志文件之外,您还可以专门启用mail()函数的日志记录 It doesn't record the complete SMTP interaction, but at least function call parameters and invocation script. 它不记录完整的SMTP交互,但至少记录函数调用参数和调用脚本。

ini_set("mail.log", "/tmp/mail.log");
ini_set("mail.add_x_header", TRUE);

See http://php.net/manual/en/mail.configuration.php for details. 有关详细信息,请参见http://php.net/manual/en/mail.configuration.php (It's best to enable these options in the php.ini or .user.ini or .htaccess perhaps.) (最好在php.ini.user.ini.htaccess启用这些选项。)

Check with a mail testing service 检查邮件测试服务

There are various delivery and spamminess checking services you can utilize to test your MTA/webserver setup. 您可以使用各种交付和垃圾邮件检查服务来测试MTA / Web服务器的设置。 Typically you send a mail probe To: their address, then get a delivery report and more concrete failures or analyzations later: 通常,您将邮件探针发送到:他们的地址,然后获取传递报告以及稍后的更具体的故障或分析:

Use a different mailer 使用其他邮件

PHP's built in mail() function is handy and often gets the job done but it has its shortcomings . PHP的内置mail()函数很方便,通常可以完成工作,但是它也有缺点 Fortunately there are alternatives that offer more power and flexibility including handling a lot of the issues outlined above: 幸运的是,有一些替代方案可以提供更大的功能和灵活性,包括处理上面概述的许多问题:

All of which can be combined with a professional SMTP server/service provider. 所有这些都可以与专业的SMTP服务器/服务提供商结合使用。 (Because typical 08/15 shared webhosting plans are hit or miss when it comes to email setup/configurability.) (因为在电子邮件设置/可配置性方面,典型的08/15共享Web托管计划会受到打击或错过。)


#3楼

If you are using an SMTP configuration for sending your email, try using PHPMailer instead. 如果您使用SMTP配置发送电子邮件,请尝试使用PHPMailer You can download the library from https://github.com/PHPMailer/PHPMailer . 您可以从https://github.com/PHPMailer/PHPMailer下载该库。

I created my email sending this way: 我创建了以这种方式发送的电子邮件:

function send_mail($email, $recipient_name, $message='')
{
    require("phpmailer/class.phpmailer.php");

    $mail = new PHPMailer();

    $mail->CharSet = "utf-8";
    $mail->IsSMTP();                                      // Set mailer to use SMTP
    $mail->Host = "mail.example.com";  // Specify main and backup server
    $mail->SMTPAuth = true;     // Turn on SMTP authentication
    $mail->Username = "myusername";  // SMTP username
    $mail->Password = "p@ssw0rd"; // SMTP password

    $mail->From = "me@walalang.com";
    $mail->FromName = "System-Ad";
    $mail->AddAddress($email, $recipient_name);

    $mail->WordWrap = 50;                                 // Set word wrap to 50 characters
    $mail->IsHTML(true);                                  // Set email format to HTML (true) or plain text (false)

    $mail->Subject = "This is a Sampleenter code here Email";
    $mail->Body    = $message;
    $mail->AltBody = "This is the body in plain text for non-HTML mail clients";
    $mail->AddEmbeddedImage('images/logo.png', 'logo', 'logo.png');
    $mail->addAttachment('files/file.xlsx');

    if(!$mail->Send())
    {
       echo "Message could not be sent. <p>";
       echo "Mailer Error: " . $mail->ErrorInfo;
       exit;
    }

    echo "Message has been sent";
}

#4楼

Just add some headers before sending mail: 在发送邮件之前,只需添加一些标题即可:

<?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";

$headers .= "MIME-Version: 1.0\r\n";
$headers .= "Content-type: text/html\r\n";
$headers .= 'From: from@example.com' . "\r\n" .
'Reply-To: reply@example.com' . "\r\n" .
'X-Mailer: PHP/' . phpversion();

mail($to, $subject, $message, $headers);

And one more thing. 还有一件事情。 The mail() function is not working in localhost. mail()函数在localhost中不起作用。 Upload your code to a server and try. 将您的代码上传到服务器,然后尝试。


#5楼

If you only use the mail() function, you need to complete the configuration file. 如果仅使用mail()函数,则需要完成配置文件。

You need to open the mail expansion, and set the SMTP smtp_port and so on, and most important, your username and your password. 您需要打开邮件扩展,并设置SMTP smtp_port等,最重要的是您的用户名和密码。 Without that, mail cannot be sent. 否则,将无法发送邮件。 Also, you can use the PHPMail class to send. 另外,您可以使用PHPMail类进行发送。


#6楼

You can use config email by CodeIgniter . 您可以通过CodeIgniter使用配置电子邮件。 For example, using SMTP (simple way): 例如,使用SMTP (简单方式):

$config = Array(
        'protocol' => 'smtp',
        'smtp_host' => 'mail.domain.com', // Your SMTP host
        'smtp_port' => 26, // Default port for SMTP
        'smtp_user' => 'name@domain.com',
        'smtp_pass' => 'password',
        'mailtype' => 'html',
        'charset' => 'iso-8859-1',
        'wordwrap' => TRUE
);
$message = 'Your msg';
$this->load->library('email', $config);
$this->email->from('name@domain.com', 'Title');
$this->email->to('emaildestination@domain.com');
$this->email->subject('Header');
$this->email->message($message);

if($this->email->send()) 
{
   // Conditional true
}

It works for me! 这个对我有用!

  • 0
    点赞
  • 0
    评论
  • 1
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值