繁体   English   中英

PHP 邮件 function 没有完成邮件发送

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

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

尽管此答案的某些部分仅适用于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()的调用没有至少三个参数,它将失败。

如果您对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.examplepostmaster@yourdomain.example 这意味着 - 确保这些帐户存在,阅读发送给他们的内容,并对投诉采取行动。
  • 最后,让退订变得非常容易。 否则,您的用户将通过按垃圾邮件按钮取消订阅,这将影响您的声誉。

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

确保提供所有邮件标题

如果邮件缺少常见的标头,例如“From”和“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);

确保邮件标头没有语法错误

无效的标头与没有标头一样糟糕。 一个不正确的字符可能会导致您的电子邮件脱轨。 仔细检查以确保您的语法正确,因为 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: 发件人,但您不能只使用任何值。 特别是用户提供的发件人地址是阻止邮件的可靠方法:

$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 提供的电子邮件帐户)。

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

确保代码与表单方法匹配

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

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

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

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

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

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

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

确保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 共享虚拟主机计划会受到影响。)

在邮件函数中添加邮件头:

$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>';
}
  1. 始终尝试在邮件功能中发送标头。
  2. 如果您通过 localhost 发送邮件,请进行 SMTP 设置以发送邮件。
  3. 如果您通过服务器发送邮件,请检查您的服务器上是否启用了电子邮件发送功能。

如果您使用 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";
}

在发送邮件之前添加一些标题:

<?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()函数在本地主机中不起作用。 将您的代码上传到服务器并尝试。

通过执行以下操作,它在 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)

使用''而不是""

此代码有效,但收到电子邮件时延迟了半小时。

大多数情况下,共享主机中禁用了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;
    } 
}
?>

联系电子邮件.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();
}
?>

如果只使用mail()函数,则需要完成配置文件。

您需要打开邮件扩展,设置SMTP smtp_port等,最重要的是您的用户名和密码。 没有它,邮件就无法发送。 此外,您可以使用PHPMail类发送。

分别和一起尝试这两件事:

  1. 删除if($_POST['submit']){}
  2. $from

我认为这应该可以解决问题。 我刚刚添加了一个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>'; 
    }
}

?>

对于任何发现这种情况的人,我不建议使用mail 有一些答案涉及到这一点,但不是为什么

PHP 的mail功能不仅不透明,它完全依赖于您使用的任何MTA (即Sendmail )来完成工作。 mail只会告诉您 MTA 是否无法接受它(即,当您尝试发送时,Sendmail 已关闭)。 它无法告诉您邮件是否成功,因为它已将其发送出去。 因此(如John Conde 的回答详细信息),您现在可以摆弄 MTA 的日志,并希望它能告诉您足够多的有关无法修复它的信息。 如果您在共享主机上或无权访问 MTA 日志,那么您就不走运了。 可悲的是,大多数 Linux 香草安装的默认设置都是这样处理的。

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

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

如果您正在使用 SMTP(即您正在调用isSMTP() ),您可以使用SMTPDebug属性获取 SMTP 对话的详细记录。

通过在脚本中包含这样的行来设置此选项:

 $mail->SMTPDebug = 2;

您还可以从更好的界面中受益。 对于mail ,您必须设置所有标题、附件等。对于库,您有一个专门的功能来做到这一点。 这也意味着该函数正在处理所有棘手的部分(如标题)。

您可以使用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
}

这个对我有用!

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

尝试这个:

<?php
    $to = "somebody@example.com, somebodyelse@example.com";
    $subject = "HTML email";

    $message = "
        <html>
        <head>
           <title>HTML email</title>
        </head>
        <body>
          <p>This email contains HTML Tags!</p>
          <table>
            <tr>
             <th>Firstname</th>
             <th>Lastname</th>
            </tr>
            <tr>
              <td>John</td>
              <td>Doe</td>
            </tr>
          </table>
        </body>
        </html>";

    // Always set content-type when sending HTML email
    $headers = "MIME-Version: 1.0" . "\r\n";
    $headers .= "Content-type:text/html;charset=UTF-8" . "\r\n";

    // More headers
    $headers .= 'From: <webmaster@example.com>' . "\r\n";
    $headers .= 'Cc: myboss@example.com' . "\r\n";

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

尝试这个

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

可能问题出在邮件服务器的配置上。 为避免此类问题或您不必担心邮件服务器问题,我建议您使用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;
}

首先,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.)按该顺序排列,否则有可能无法正常工作。

如果您在使用 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 的更多信息,请参阅官方文档

这只会影响一小部分用户,但我希望为那一小部分用户记录下来。 由于这个问题,一小撮人中的这个成员花费了 6 个小时对一个工作的 PHP 邮件脚本进行故障排除。

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

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

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

PHP 发送邮件的方式在[mail function]部分的php.ini中进行了描述。

参数sendmail-path描述了 sendmail 是如何被调用的。 默认值是sendmail -t -i ,所以如果你在 Linux 控制台中得到一个工作的sendmail -t -i < message.txt - 你就完成了。 您还可以添加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

确保您的服务器中安装了 Sendmail。

如果您检查了代码并确认那里没有问题,请转到 /var/mail 并检查该文件夹是否为空。

如果它是空的,您将需要执行以下操作:

sudo apt-get install sendmail

如果您在 Ubuntu 服务器上。

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 个小时……别忘了检查你的垃圾邮件文件夹

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

如果您使用免费的托管服务,例如000webhosthostinger ,这些服务提供商会禁用mail()功能以防止意外使用电子邮件欺骗、垃圾邮件等。我希望您与他们联系,看看他们是否支持这一点特征。

如果您确定服务提供商支持 mail() 函数,您可以查看此 PHP 手册以供进一步参考,

PHP 邮件()

要检查您的托管服务是否支持 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);
?>

您可以使用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();
}

您可以使用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

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

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

如果您对托管在 Hostgator 上的应用程序感到困惑,就是解决我的问题的方法。 非常感谢发布详细解决方案的人。 万一有一天链接掉线了,你有总结:

  • 在您的服务器中查找 sendmail 路径。 一个简单的检查方法是在一个只有你可以访问的页面中临时编写以下代码,以读取生成的信息: <?php phpinfo(); ?> <?php phpinfo(); ?> . 打开此页面,然后查找sendmail path (然后,不要忘记删除此代码!)
  • 问题和修复:如果您的 sendmail 路径只显示-t -i ,则编辑服务器的php.ini并添加以下行: sendmail_path = /usr/sbin/sendmail -t -i;

但是,在能够使用 PHP mail()函数发送邮件后,我了解到它发送的是未经身份验证的电子邮件,这又造成了另一个问题。 邮件都掉进了我Hotmail的垃圾邮箱里,有些邮件从来没有送过,我想这与他们没有经过身份验证有关。 毕竟,这就是为什么我决定使用 SMTP 从mail()切换到PHPMailer

这部分 $headers 中的“From:”$email 地址可能有问题:

From: \"$name\" <$email>

要试用它,请发送一封不带标题部分的电子邮件,例如:

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

如果是这种情况,请尝试使用已在您尝试发送邮件的系统上创建的电子邮件帐户。

<?php

$to       = 'name@example.com';
$subject  = 'Write your email subject here.';
$message  = '
<html>
<head>
<title>Title here</title>
</head>
<body>
<p>Message here</p>
</body>
</html>
';

// Carriage return type (RFC).
$eol = "\r\n";

$headers  = "Reply-To: Name <name@example.com>".$eol;
$headers .= "Return-Path: Name <name@example.com>".$eol;
$headers .= "From: Name <name@example.com>".$eol;
$headers .= "Organization: Hostinger".$eol;
$headers .= "MIME-Version: 1.0".$eol;
$headers .= "Content-type: text/html; charset=iso-8859-1".$eol;
$headers .= "X-Priority: 3".$eol;
$headers .= "X-Mailer: PHP".phpversion().$eol;


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

发送 HTML 电子邮件发送电子邮件时,您可以指定 Mime 版本、内容类型和字符集以发送 HTML 电子邮件。

示例上面的示例将向 name@example.com 发送 HTML 电子邮件消息。 您可以对这个程序进行编码,使其接收用户的所有内容,然后发送电子邮件。

为我解决了这个问题的是某些提供商在使用 php 邮件时不允许外部收件人:

将代码中的收件人($recipient)更改为本地收件人。 这意味着使用来自服务器域的电子邮件地址,例如,如果您的服务器域是www.yourdomain.com ,那么收件人的电子邮件应该是某人@yourdomain.com。 上传修改后的php文件并重试。 如果它仍然不起作用:将发件人 ($sender) 更改为本地电子邮件(使用与收件人相同的电子邮件)。 上传修改后的php文件并重试。

希望这会有所帮助! https://www.arclab.com/en/kb/php/how-to-test-and-fix-php-mail-function.html

我遇到了这个问题,发现剥离标题有助于我将邮件发送出去。 所以这:

$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 抛出了新行。 我很欣赏这不是编码纯粹主义者的方法,但它可以满足我的需要。

在我的例子中,email 被很好地发送但被接收,因为整个消息在一行中超过 998 个字符。 我需要使用以下行使最大长度为 70 的行: wordwrap($email_message, 70, "\r\n"); .

https://www.rfc-editor.org/rfc/rfc5322#section-2.1.1

There are two limits that this specification places on the number of characters in a line. Each line of characters MUST be no more than 998 characters, and SHOULD be no more than 78 characters, excluding the CRLF.

有几种可能性:

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

  2. 您没有获得发布的价值。 尝试使用静态值的代码。

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

对于从 gmail smtp 发送电子邮件和使用 php 邮件功能,首先你必须在本地机器上设置 sendmail,一旦设置就意味着你已经设置了本地 smtp 服务器,然后你就可以从你的帐户发送电子邮件在您的 sendmail smtp 帐户中设置,就我而言,我按照https://www.developerfiles.com/how-to-send-emails-from-localhost-mac-os-x-el-capitan/ 中的说明进行操作,并且能够设置帐户,

如果您的 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 标记作为行的开头,并且在分号之后没有空格或任何字符。

如果您使用的是PHP邮件程序,则可以使用以下代码。 只需复制粘贴,然后将***替换为您的数据和凭据即可。 并更改输入数据名称的值。

<?php
    require_once ("PHPMailer/PHPMailerAutoload.php");

    $error = array();

    //var_dump($_POST);

    $message = $_POST['a'] . '<br>';
    $message.= $_POST['b'] . '<br>';
    $message.= $_POST['c'] . '<br>';
    $message.= $_POST['d'] . '<br>';
    $message.= $_POST['e'] . '<br>';
    $message.= $_POST['f'] . '<br>';
    $message.= $_POST['g'] . '<br>';
    $message.= $_POST['h'] . '<br>';
    $message.= $_POST['i'] . '<br>';
    $message.= $_POST['j'] . '<br>';
    $message.= $_POST['k'] . '<br>';

    $subject = "Visitor Query";
    $from = "******@******.com"; // example a@b.com
    $password = '******';

    $mail = new PHPMailer();
    $body = $message;
    $mail->IsSMTP();
    $mail->SMTPAuth = true; // Turn on SMTP authentication
    $mail->SMTPKeepAlive = true; // SMTP connection will not close after each email sent, reduces SMTP overhead
    $mail->SMTPDebug = 0;

    //$mail->Host = 'mail.******.com'; // Sets SMTP server
    $mail->Host = 'mail.******.com'; // Sets SMTP server
    $mail->SMTPSecure = 'ssl';
    $mail->Port = 465;
    //$mail->Port = 25;

    $mail->Username = $from; // SMTP username
    $mail->Password = $password; // SMTP password

    $mail->AddAddress ( "******@gmail.com" );
    $mail->AddReplyTo ( "******@gmail.com", "Team");
    $mail->Subject = $subject;
    $mail->Body = $message;
    $mail->From =  $from;
    $mail->FromName = "Visitor's Query";
    $mail->ContentType = "text/html";

    if (count($error == 0)) {

         $mail->Send();

        // echo "_________________wait_______for_______ our _______ reply  !";


    } else {

        echo $error; // Show error messages
        //echo $result;
    }

    //header("location: index.php");
?>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM