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


477
<?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页面上,但是会提交到单独的“感谢您的提交”页面,thankyou.php上面的PHP代码已嵌入其中。该代码可以完美提交,但从不发送电子邮件。我怎样才能解决这个问题?


2
是您在本地计算机或实时主机中的程序
Tamil Selvan C 2014年

6
1.您确定它不会进入垃圾邮件吗?2.您的邮箱上配置了sendmail吗?
史蒂文·莫斯利

它在实时主机上不会进入我的垃圾邮件。.我不确定在我的机器上配置sendmail的意思,所以我认为不是吗?
user3818620

尝试不发送$from
邮件

Answers:


511

尽管此答案的某些部分仅适用于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()没有按正确的顺序使用正确的参数,也会失败。

检查服务器的邮件日志

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

检查端口连接失败

端口阻塞是大多数开发人员在集成其代码以使用SMTP传递电子邮件时面临的一个非常普遍的问题。并且,可以轻松地在服务器邮件日志中找到该邮件(如上所述,邮件日志的服务器位置可能因服务器而异)。如果您在共享主机服务器上,则默认情况下端口25和587仍处于阻止状态。此阻止是由您的托管服务提供商有意完成的。即使对于某些专用服务器也是如此。当这些端口被阻止时,请尝试使用端口2525进行连接。如果您发现该端口也被阻止,则唯一的解决方案是与主机提供商联系以解除对这些端口的阻止。

大多数托管服务提供商会阻止这些电子邮件端口,以保护其网络免于发送垃圾邮件。

将端口25或587用于纯/ TLS连接,将端口465用于SSL连接。对于大多数用户,建议使用端口587以避免某些托管服务提供商设置的速率限制。

不要使用错误抑制运算符

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

如果您的代码包含,@mail(...)则可能隐藏了重要的错误消息,这些消息将帮助您进行调试。删除@并查看是否报告了任何错误。

仅在事后检查是否有error_get_last()具体故障时才建议这样做。

检查mail()返回值

mail()函数:

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

注意这一点很重要,因为:

  • 如果收到FALSE返回值,则表明错误在于服务器接受您的邮件。这可能不是编码问题,而是服务器配置问题。您需要与系统管理员联系,以找出发生这种情况的原因。
  • 如果您收到TRUE返回值,并不意味着一定会发送您的电子邮件。这只是意味着电子邮件已通过PHP成功发送到服务器上的相应处理程序。在PHP的控制范围之外,还有更多故障点可能导致电子邮件无法发送。

所以,FALSE将帮助你指出正确的方向,而TRUE没有一定意味着你的电子邮件成功发送。重要的是要注意!

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

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

如果您认为您的主机有电子邮件限制或阻止发送电子邮件,请查看其常见问题解答以查看是否列出了任何此类限制。否则,您可能需要寻求他们的支持,以验证电子邮件发送周围是否存在任何限制。

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

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

为避免通过PHP发送的邮件被发送到收件人的垃圾邮件文件夹,在PHP代码和其他代码中,您都可以执行多种操作,以最大程度地减少将电子邮件标记为垃圾邮件的机会。来自Michiel de Mare的好提示包括:

  • 使用SPFDKIM之类的电子邮件身份验证方法来证明您的电子邮件和您的域名属于同一类,并防止欺骗您的域名。SPF网站包含一个向导,用于为您的站点生成DNS信息。
  • 检查您的反向DNS,以确保您的邮件服务器指向的IP地址,您用于发送邮件的域名。
  • 确保您使用的IP地址不在黑名单中
  • 确保答复地址是有效的现有地址。
  • 在“收件人”字段中使用收件人的全名,而不只是电子邮件地址(例如"John Smith" <john@blacksmiths-international.com>)。
  • 监视您的滥用帐户,例如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!

原因:您的Web或发送邮件服务器未列入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提供的电子邮件帐户)。

如果电子邮件到达所有或其他一些电子邮件帐户,则您知道您的代码正在发送电子邮件,但是电子邮件帐户提供商可能出于某种原因阻止了它们。如果电子邮件没有到达任何电子邮件帐户,则问题很可能与您的代码有关。

确保代码与form方法匹配

如果您将表单方法设置为POST,请确保您正在使用$_POST来查找表单值。如果已将其设置为GET或根本没有设置,请确保使用$_GET来查找表单值。

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

确保您的form action属性包含一个指向您的PHP邮件代码的值。

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

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

一些Web托管提供商不允许或启用通过其服务器发送电子邮件。造成这种情况的原因可能有所不同,但是如果他们禁用了邮件发送功能,则需要使用另一种方法,该方法使用第三方为您发送这些电子邮件。

给他们的技术支持的电子邮件(在访问他们的在线支持或FAQ之后)应该阐明您的服务器上是否有电子邮件功能。

确保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 / Web服务器的设置。通常,您将邮件探测发送至:他们的地址,然后获取传递报告以及稍后的更具体的故障或分析:

使用其他邮件

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

所有这些都可以与专业的SMTP服务器/服务提供商结合使用。(因为在电子邮件设置/可配置性方面,典型的08/15共享Web托管计划会受到打击或错过。)


11
约翰,写得很好。我还要添加一件事:如果有可能,检查发送邮件服务器的邮件服务器日志(无论是本地托管还是远程托管),通常可以找出引起问题的原因。这些日志应显示1)发送邮件服务器是否从PHP脚本接收到邮件,如果是,则2)接收MX是否接受来自发送邮件服务器的传递。
mti2935 2014年

@ mti2935太有用了,令我惊讶的是我错过了。我一定会尽快添加它。:)
约翰·孔德2014年

1
我会mail()

1
000webhost上的同一网站在netai.net域上成功且快速地发送了电子邮件,但在site88.net上,我在控制台中获得了与该邮件成功发送的控制台相同的网站,但是我没有收到任何消息。同样在comuf.com域中,我也会收到错误消息。(同一主机上的同一网站只能在netai.net域上工作,net16.net也可以)
Nicolas Papaconstantinou

1
我的问题(stackoverflow.com/questions/44866673/…)被标记为与此重复的问题,但我仍然无法弄清楚。有什么建议么?
扎卡里·埃尔金斯

37

在mail函数中添加一个邮件头:

$header = "From: noreply@example.com\r\n";
$header.= "MIME-Version: 1.0\r\n";
$header.= "Content-Type: text/html; charset=ISO-8859-1\r\n";
$header.= "X-Priority: 1\r\n";

$status = mail($to, $subject, $message, $header);

if($status)
{
    echo '<p>Your mail has been sent!</p>';
} else {
    echo '<p>Something went wrong. Please try again!</p>';
}

25
  1. 始终尝试在邮件功能中发送标题。
  2. 如果要通过本地主机发送邮件,请执行SMTP设置以发送邮件。
  3. 如果要通过服务器发送邮件,请检查服务器上是否启用了电子邮件发送功能。

20

如果您使用SMTP配置发送电子邮件,请尝试使用PHPMailer。您可以从https://github.com/PHPMailer/PHPMailer下载该库。

我创建了以这种方式发送的电子邮件:

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

2
我还必须使用:require(“ phpmailer / class.smtp.php”);
Doug

15

在发送邮件之前,只需添加一些标题即可:

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

还有一件事情。该mail()功能在localhost中不起作用。将您的代码上传到服务器,然后尝试。


1
这实际上使表单提交了–我的问题现在是..我如何显示用户在电子邮件中输入的内容,现在我已将其替换为标头...
user3818620 2014年

它将阻止来自垃圾邮件文件夹的邮件。我看过是否使用您在代码gmail中使用的这种方法发送的邮件超过10条,并将此邮件发送到垃圾邮件。
jewelhuq

OP的这一行:$from = 'From: yoursite.com'; 它看起来不像一个完整的有效电子邮件地址,没有本地部分。您已替换了From标头,并添加了其他标头。或更确切地说,$from以上内容在您的示例中是多余的。畸形可能是OP的原始问题。
Progrock '16

13

通过执行以下操作,它在000webhost上为我工作:

$headers  = "MIME-Version: 1.0" . "\r\n";
$headers .= "Content-type: text/html; charset=iso-8859-1" . "\r\n";
$headers .= "From: ". $from. "\r\n";
$headers .= "Reply-To: ". $from. "\r\n";
$headers .= "X-Mailer: PHP/" . phpversion();
$headers .= "X-Priority: 1" . "\r\n";

发送电子邮件时直接输入电子邮件地址:

mail('email@gmail.com', $subject, $message, $headers)

使用''而不是""

该代码有效,但是收到电子邮件的时间为半小时。


10

通常,该mail()功能在共享主机中被禁用。更好的选择是使用SMTP。最好的选择是Gmail或SendGrid。


SMTPconfig.php

<?php 
    $SmtpServer="smtp.*.*";
    $SmtpPort="2525"; //default
    $SmtpUser="***";
    $SmtpPass="***";
?>

SMTPmail.php

<?php
class SMTPClient
{

    function SMTPClient ($SmtpServer, $SmtpPort, $SmtpUser, $SmtpPass, $from, $to, $subject, $body)
    {

        $this->SmtpServer = $SmtpServer;
        $this->SmtpUser = base64_encode ($SmtpUser);
        $this->SmtpPass = base64_encode ($SmtpPass);
        $this->from = $from;
        $this->to = $to;
        $this->subject = $subject;
        $this->body = $body;

        if ($SmtpPort == "") 
        {
            $this->PortSMTP = 25;
        }
        else
        {
            $this->PortSMTP = $SmtpPort;
        }
    }

    function SendMail ()
    {
        $newLine = "\r\n";
        $headers = "MIME-Version: 1.0" . $newLine;  
        $headers .= "Content-type: text/html; charset=iso-8859-1" . $newLine;  

        if ($SMTPIN = fsockopen ($this->SmtpServer, $this->PortSMTP)) 
        {
            fputs ($SMTPIN, "EHLO ".$HTTP_HOST."\r\n"); 
            $talk["hello"] = fgets ( $SMTPIN, 1024 ); 
            fputs($SMTPIN, "auth login\r\n");
            $talk["res"]=fgets($SMTPIN,1024);
            fputs($SMTPIN, $this->SmtpUser."\r\n");
            $talk["user"]=fgets($SMTPIN,1024);
            fputs($SMTPIN, $this->SmtpPass."\r\n");
            $talk["pass"]=fgets($SMTPIN,256);
            fputs ($SMTPIN, "MAIL FROM: <".$this->from.">\r\n"); 
            $talk["From"] = fgets ( $SMTPIN, 1024 ); 
            fputs ($SMTPIN, "RCPT TO: <".$this->to.">\r\n"); 
            $talk["To"] = fgets ($SMTPIN, 1024); 
            fputs($SMTPIN, "DATA\r\n");
            $talk["data"]=fgets( $SMTPIN,1024 );
            fputs($SMTPIN, "To: <".$this->to.">\r\nFrom: <".$this->from.">\r\n".$headers."\n\nSubject:".$this->subject."\r\n\r\n\r\n".$this->body."\r\n.\r\n");
            $talk["send"]=fgets($SMTPIN,256);
            //CLOSE CONNECTION AND EXIT ... 
            fputs ($SMTPIN, "QUIT\r\n"); 
            fclose($SMTPIN); 
            // 
        } 
        return $talk;
    } 
}
?>

contact_email.php

<?php 
include('SMTPconfig.php');
include('SMTPmail.php');
if($_SERVER["REQUEST_METHOD"] == "POST")
{
    $to = "";
    $from = $_POST['email'];
    $subject = "Enquiry";
    $body = $_POST['name'].'</br>'.$_POST['companyName'].'</br>'.$_POST['tel'].'</br>'.'<hr />'.$_POST['message'];
    $SMTPMail = new SMTPClient ($SmtpServer, $SmtpPort, $SmtpUser, $SmtpPass, $from, $to, $subject, $body);
    $SMTPChat = $SMTPMail->SendMail();
}
?>

将smtp用户名和密码以纯文本格式保存在服务器上是个好主意吗?
朱里

@Juri可能不是...天哪,我无法弄清楚如何使邮件功能正常工作..(

9

如果仅使用该mail()功能,则需要完成配置文件。

您需要打开邮件扩展,并设置SMTP smtp_port等等,最重要的是您的用户名和密码。否则,将无法发送邮件。另外,您可以使用PHPMail该类进行发送。


9

分别或同时尝试这两件事:

  1. 去除 if($_POST['submit']){}
  2. 移开$from(只是我的内脏)

8

我认为这应该可以解决问题。我刚刚if(isset在正文中的变量中添加了,并添加了串联以将PHP与HTML分开。

<?php
    $name = $_POST['name'];
    $email = $_POST['email'];
    $message = $_POST['message'];
    $from = 'From: yoursite.com'; 
    $to = 'contact@yoursite.com'; 
    $subject = 'Customer Inquiry';
    $body = "From:" .$name."\r\n E-Mail:" .$email."\r\n Message:\r\n" .$message;

if (isset($_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>'; 
    }
}

?>

8

对于任何发现这种情况的人,我不建议使用mail。有一些与此有关的答案,但不是其原因

PHP的mail功能不仅不透明,而且完全依赖于您使用的任何MTA(即Sendmail)来完成工作。mail告诉你,如果MTA没有接受它(即Sendmail的下跌,当你试图发送)。它无法告诉您邮件是否成功,因为它已被传递。因此(如约翰·康德的回答详细信息),您现在可以摆弄MTA的日志,并希望它告诉您有关修复它的失败的足够信息。如果您在共享主机上,或者无法访问MTA日志,那么您就不走运了。可悲的是,大多数Linux原始安装的默认设置都是以这种方式处理的。

邮件库(PHPMailer,Zend Framework 2+等)的功能与完全不同mail。他们直接打开一个到接收邮件服务器的套接字,然后直接通过该套接字发送SMTP邮件命令。换句话说,该类充当其自己的MTA(请注意,您可以告诉库mail用来最终发送邮件,但我强烈建议您不要这样做)。

这意味着您可以直接查看来自接收服务器的响应(例如,在PHPMailer中,您可以打开调试输出)。无需再猜测邮件是否发送失败或原因。

如果您使用的是SMTP(即您正在呼叫isSMTP()),则可以使用SMTPDebug属性获得SMTP会话的详细记录。

通过在脚本中包含以下行来设置此选项:

$mail->SMTPDebug = 2;

您还将受益于更好的界面。随着mail你必须设置你所有的标题,附件等与图书馆,你有一个专门的函数来做到这一点。这也意味着该函数正在执行所有棘手的部分(例如标头)。


6
$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>";
}

6

您可以通过CodeIgniter使用配置电子邮件。例如,使用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
}

这个对我有用!


1
fsockopen()[function.fsockopen]:php_network_getaddresses:getaddrinfo失败:此类主机未知。-如果我遇到此错误,那是什么原因,需要做什么?
Choudhury Saadmaan Mahmid 2015年

1
“为我工作”只是轶事,但实际上并没有太多解释。端口和smtp密码对于大多数用户而言会产生误导。
马里奥

什么是“配置电子邮件”?你有参考吗?
彼得·莫滕森

4

尝试这个

if ($_POST['submit']) {
    $success= mail($to, $subject, $body, $from);
    if($success)
    { 
        echo '
        <p>Your message has been sent!</p>
        ';
    } else { 
        echo '
        <p>Something went wrong, go back and try again!</p>
        '; 
    }
}

4

可能问题是邮件服务器的配置。为了避免此类问题,或者您不必担心邮件服务器问题,建议您使用PHPMailer

它是一个具有发送邮件所需的一切的插件,您唯一需要考虑的就是启用SMTP端口(端口:25和465)。

require_once 'PHPMailer/PHPMailer.php';
require_once '/servicios/PHPMailer/SMTP.php';
require_once '/servicios/PHPMailer/Exception.php';

$mail = new \PHPMailer\PHPMailer\PHPMailer(true);
try {
    //Server settings
    $mail->SMTPDebug = 0;
    $mail->isSMTP();
    $mail->Host = 'smtp.gmail.com';
    $mail->SMTPAuth = true;
    $mail->Username = 'correo@gmail.com';
    $mail->Password = 'contrasenia';
    $mail->SMTPSecure = 'ssl';
    $mail->Port = 465;

    // Recipients
    $mail->setFrom('correo@gmail.com', 'my name');
    $mail->addAddress('destination@correo.com');

    // Attachments
    $mail->addAttachment('optional file');         // Add files, is optional

    // Content
    $mail->isHTML(true);// Set email format to HTML
    $mail->Subject = utf8_decode("subject");
    $mail->Body    = utf8_decode("mail content");
    $mail->AltBody = '';
    $mail->send();
}
catch (Exception $e) {
    $error = $mail->ErrorInfo;
}

1
IANA已将端口465替换为端口587。这是默认的邮件提交端口。当电子邮件客户端或传出服务器提交要由适当的邮件服务器路由的电子邮件时,应始终使用SMTP端口587作为默认端口。请参阅mailgun.com/blog/which-smtp-port-understanding-ports-25-465-587。明智的建议:如果您不完全了解自己在做什么,请不要打开计算机上的端口!
有害

3

确保在服务器中安装了Sendmail。

如果您已检查代码并验证那里没有问题,请转至/ var / mail并检查该文件夹是否为空。

如果为空,则需要执行以下操作:

sudo apt-get install sendmail

如果您在Ubuntu服务器上。


那太粗糙了而无用。仅安装MTA很少会允许它。完整的sendmail / postfix / qmail设置指南将不在这里。
mario

此评论是否参考了我的答案?因为这还没有发生在我身上,我也没有以完全相同的方式解决。该问题有多种可能的答案,过去曾尝试过上述所有方法,但我只是其中之一,我的答案已为我解决了这个问题,因此在这里我将其提供为另一种可能的解决方案。
丹尼尔(Daniel)

是的,可以。这是许多可能的答案之一。但是,这仍然是表面化IMO的方法。将其概括为“您需要MTA”,例如…-这是一些链接的设置指南…但是可能更实用。
mario

3

首先,您可能为mail()函数设置了太多参数...您最多可以有五个参数, mail(to, subject, message, headers, parameters);

$from变量而言,如果您使用的是Linux cPanel,则该变量应该自动来自您的网络主机。它自动来自您的cPanel用户名和IP地址。

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

另外,请确保您在mail()函数中具有正确的变量顺序。

mail($to, $subject, $message, etc.)按照这个顺序,否则有它不工作的机会。


3

如果您在使用PHP发送邮件时遇到问题,请考虑使用PHPMailerSwiftMailer之类的替代方法。

每当需要使用PHP发送邮件时,我通常都会使用SwiftMailer。


基本用法:

require 'mail/swift_required.php';

$message = Swift_Message::newInstance()
    // The subject of your email
    ->setSubject('Jane Doe sends you a message')
    // The from address(es)
    ->setFrom(array('jane.doe@gmail.com' => 'Jane Doe'))
    // The to address(es)
    ->setTo(array('frank.stevens@gmail.com' => 'Frank Stevens'))
    // Here, you put the content of your email
    ->setBody('<h3>New message</h3><p>Here goes the rest of my message</p>', 'text/html');

if (Swift_Mailer::newInstance(Swift_MailTransport::newInstance())->send($message)) {
    echo json_encode([
        "status" => "OK",
        "message" => 'Your message has been sent!'
    ], JSON_PRETTY_PRINT);
} else {
    echo json_encode([
        "status" => "error",
        "message" => 'Oops! Something went wrong!'
    ], JSON_PRETTY_PRINT);
}

有关如何使用SwiftMailer的更多信息,请参见官方文档


3

对于那些不想使用外部邮件程序并希望在专用Linux服务器上使用mail()的用户。

php.ini节中介绍了PHP邮件发送方式。[mail function]

该参数sendmail-path描述了sendmail的调用方式。默认值为sendmail -t -i,因此,如果您可以sendmail -t -i < message.txt在Linux控制台中工作-便可以完成。您还可以添加mail.log调试,并确保确实调用了mail()。

可以实现不同的MTA sendmail。他们只是在该名称上建立了指向其二进制文件的符号链接。例如,在Debian中,默认值为Postfix。配置您的MTA以发送邮件,并使用控制台从控制台对其进行测试sendmail -v -t -i < message.txt。文件message.txt应包含邮件的所有标头和正文,信封的目标地址将从To:标头中获取。例:

From: myapp@example.com
To: mymail@example.com
Subject: Test mail via sendmail.

Text body.

我更喜欢使用ssmtp作为MTA,因为它很简单并且不需要运行带有打开端口的守护程序。ssmtp仅适用于从localhost发送邮件。它还可以通过您在公共邮件服务上的帐户发送经过身份验证的电子邮件。安装ssmtp并编辑配置文件/etc/ssmtp/ssmtp.conf。为了能够接收到本地系统邮件到Unix帐户(例如,从cron作业向root发出警报),请配置/etc/ssmtp/revaliases文件。

这是我在Yandex邮件中帐户的配置:

root=mymail@example.com
mailhub=smtp.yandex.ru:465
FromLineOverride=YES
UseTLS=YES
AuthUser=abcde@yandex.ru
AuthPass=password

2

这只会影响一小部分用户,但我希望为那小部分用户提供文档。由于这个问题,这个少数的成员花了6个小时来对可用的PHP邮件脚本进行故障排除。

如果要去从www.AceITLab.com运行XAMPP的大学,您应该知道我们的教授没有告诉我们什么:AceITLab防火墙(不是Windows防火墙)阻止XAMPP中的MercuryMail。您将不得不使用备用邮件客户端,梨正在为我们工作。您必须发送到安全设置较低的Gmail帐户。

是的,我知道,这对于现实世界的电子邮件完全没有用。但是,据我所见,学术环境和现实世界通常没有什么共同之处。


这太奇怪了,确实对其他人没有帮助。请使用您答案下方的[删除]链接。
mario

在这种情况下,“梨”是什么?您的意思是PHP软件仓库PEAR吗?或者是其他东西?例如同行
彼得·莫滕森

您真的是“珍贵的小孩子”吗?有什么希望吗?为什么?
彼得·莫滕森

1

如果您在本地服务器(即用于开发目的的计算机)上运行此代码,则不会将电子邮件发送给收件人。它将.txt在名为的文件夹中创建一个文件mailoutput

如果您正在使用免费的托管服务(例如000webhost或)hostinger,则这些服务提供商会禁用该mail()功能以防止意外使用电子邮件欺骗,垃圾邮件等。我希望您与他们联系以了解他们是否支持此功能。

如果您确定服务提供商支持mail()函数,则可以查看此PHP手册以获取更多参考,

PHP mail()

要检查您的托管服务是否支持mail()函数,请尝试运行以下代码(切记更改收件人电子邮件地址)

<?php
    $to      = 'nobody@example.com';
    $subject = 'the subject';
    $message = 'hello';
    $headers = 'From: webmaster@example.com' . "\r\n" .
        'Reply-To: webmaster@example.com' . "\r\n" .
        'X-Mailer: PHP/' . phpversion();

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

1

Debian 10.0.0(“ Buster”)的 Sendmail安装实际上很简单!

php.ini

[mail function]
sendmail_path=/usr/sbin/sendmail -t -i
; (Other directives are mostly windows)

标准sendmail软件包安装(允许“发送”):

su -                                        # Install as user 'root'
dpkg --list                                 # Is install necessary?
apt-get install sendmail sendmail-cf m4     # Note multiple package selection
sendmailconfig                              # Respond all 'Y' for new install

其他有用的命令:

which sendmail                              # /usr/sbin/sendmail
which sendmailconfig                        # /usr/sbin/sendmailconfig
man sendmail                                # Documentation
systemctl restart sendmail                  # As and when required

验证(发送能力)

echo "Subject: sendmail test" | sendmail -v <yourEmail>@gmail.com

以上过程大约花费了5分钟。然后我浪费了5个小时... 别忘了检查您的垃圾邮件文件夹


0

有几种可能性:

  1. 您正面临服务器问题。该服务器没有任何邮件服务器。因此您的邮件无法正常工作,因为您的代码正常并且邮件可以使用type。

  2. 您没有得到过帐的值。尝试使用静态值的代码。

  3. 使用SMTP邮件发送邮件...


0

您可以使用libmail:http ://lwest.free.fr/doc/php/lib/index.php3?page=mail&lang=en

include "libmail.php";
$m = new Mail(); // Create the mail
$m->From($_POST['form']);
$m->To($_POST['to']);
$m->Subject($_POST['subject']);
$m->Body($_POST['body']);
$m->Cc($_POST['cc']);
$m->Priority(4);
// Attach a file of type 'image/gif' to be displayed in the message if possible
$m->Attach("/home/leo/toto.gif", "image/gif", "inline");
$m->Send(); // Send the mail
echo "Mail was sent:"
echo $m->Get(); // Show the mail source

5
值得一提的是:这仅仅是一个mail()函数包装器。仅添加消息构造和一些头。
mario

0

您可以通过以下方式查看错误:

error_reporting(E_ALL);

我的示例代码是:

<?php
    use PHPMailer\PHPMailer\PHPMailer;
    require 'PHPMailer.php';
    require 'SMTP.php';
    require 'Exception.php';

    $name = $_POST['name'];
    $mailid = $_POST['mail'];
    $mail = new PHPMailer;
    $mail->IsSMTP();
    $mail->SMTPDebug = 0;                   // Set mailer to use SMTP
    $mail->Host = 'smtp.gmail.com';         // Specify main and backup server
    $mail->Port = 587;                      // Set the SMTP port
    $mail->SMTPAuth = true;                 // Enable SMTP authentication
    $mail->Username = 'someone@gmail.com';  // SMTP username
    $mail->Password = 'password';           // SMTP password
    $mail->SMTPSecure = 'tls';              // Enable encryption, 'ssl' also accepted

    $mail->From = 'someone@gmail.com';
    $mail->FromName = 'name';
    $mail->AddAddress($mailid, $name);       // Name is optional
    $mail->IsHTML(true);                     // Set email format to HTML
    $mail->Subject = 'Here is the subject';
    $mail->Body    = 'Here is your message' ;
    $mail->AltBody = 'This is the body in plain text for non-HTML mail clients';
    if (!$mail->Send()) {
       echo 'Message could not be sent.';
       echo 'Mailer Error: ' . $mail->ErrorInfo;
       exit;
    }
    echo 'Message has been sent';
?>

1
SMTPDebug = 0没有帮助。GMail也无法使用简单的“密码”。这个答案在这里贡献不大。
mario

-2

如果您的sendmail系统正常运行,则必须按如下所示修改您的代码:

<?php
    $name = $_POST['name'];
    $email = $_POST['email'];
    $message = $_POST['message'];

    $header ="
Content-Type: text/html; charset=UTF-8\r\n
MIME-Version: 1.0\r\n
From: \"$name\" <$email>\r\n
Reply-To: no-reply@yoursite.com\r\n
X-Mailer: yoursite.com mailer\r\n
";

    $to = '"Contact" <contact@yoursite.com>'; 
    $subject = 'Customer Inquiry';
    $body =<<<EOB
<!DOCTYPE html>
<html>
    <body>
        $message
    </body>
</html>
EOB;

    if ($_POST['submit']) {
        if (mail ($to, $subject, $body, $header) !== false) { 
            echo '<p>Your message has been sent!</p>';
        } else { 
            echo '<p>Something went wrong, go back and try again!</p>'; 
        }
    }
?>

这使您能够发送基于HTML的电子邮件。

值得注意的是:

  1. 我们构建了一个标题多行字符串(每行用\ r \ n分隔);
  2. 我们添加了Content-type来表示我们返回HTML,以便您编写更好的电子邮件(可以像在HTML页面中一样在邮件中添加所需的HTML代码,包括CSS)。

注意:<<<EOB语法要求最后一个EOB标记从行首开始,并且在分号后不能有空格或任何字符。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.