提问人:user3818620 提问时间:7/9/2014 最后编辑:John Slegersuser3818620 更新时间:5/14/2023 访问量:528466
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 = '[email protected]';
$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>';
}
}
?>
我尝试创建一个简单的邮件表单。表单本身在我的页面上,但它提交到一个单独的“感谢您的提交”页面,其中嵌入了上述PHP代码。
代码可以完美地提交,但从不发送电子邮件。我该如何解决这个问题?index.html
thankyou.php
答:
尽管这个答案的某些部分仅适用于mail()
函数本身的使用,但其中许多故障排除步骤可以应用于任何 PHP 邮件系统。
脚本似乎不发送电子邮件的原因有很多。除非存在明显的语法错误,否则很难诊断这些事情。如果没有,您需要浏览下面的清单,以找到您可能遇到的任何潜在陷阱。
确保错误报告已启用并设置为报告所有错误
错误报告对于根除代码中的错误和 PHP 遇到的一般错误至关重要。需要启用错误报告才能接收这些错误。将以下代码放在 PHP 文件的顶部(或主配置文件中)将启用错误报告。
error_reporting(-1);
ini_set('display_errors', 'On');
set_error_handler("var_dump");
请参阅如何在PHP中获取有用的错误消息?-此答案以获取更多详细信息。
确保调用该函数mail()
这可能看起来很傻,但一个常见的错误是忘记将函数实际放置在代码中。确保它在那里并且没有被注释掉。mail()
确保正确调用函数mail()
bool 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
- 如果您收到返回值,这并不意味着您的电子邮件一定会被发送。这只是意味着PHP已将电子邮件成功发送到服务器上的相应处理程序。还有更多超出PHP控制范围的故障点,可能导致电子邮件无法发送。
TRUE
因此,这将有助于为您指明正确的方向,但并不一定意味着您的电子邮件已成功发送。这一点很重要!FALSE
TRUE
确保您的托管服务提供商允许您发送电子邮件并且不限制邮件发送
许多共享虚拟主机,尤其是免费虚拟主机提供商,要么不允许从其服务器发送电子邮件,要么限制在任何给定时间段内可以发送的数量。这是由于他们努力限制垃圾邮件发送者利用其更便宜的服务。
如果您认为您的房东有电子邮件发送限制或阻止发送电子邮件,请查看他们的常见问题解答,看看他们是否列出了任何此类限制。否则,您可能需要联系他们的支持人员,以验证发送电子邮件是否有任何限制。
检查垃圾邮件文件夹;防止电子邮件被标记为垃圾邮件
通常,由于各种原因,通过 PHP(和其他服务器端编程语言)发送的电子邮件最终会进入收件人的垃圾邮件文件夹。在对代码进行故障排除之前,请务必检查那里。
为了避免通过 PHP 发送的邮件被发送到收件人的垃圾邮件文件夹,您可以在 PHP 代码和其他代码中执行各种操作,以最大程度地减少电子邮件被标记为垃圾邮件的机会。Michiel de Mare的好建议包括:
- 使用电子邮件身份验证方法(例如 SPF 和 DKIM)来证明您的电子邮件和域名属于一起,并防止您的域名被欺骗。SPF 网站包含一个向导,用于生成站点的 DNS 信息。
- 检查您的反向 DNS,确保邮件服务器的 IP 地址指向您用于发送邮件的域名。
- 确保您使用的 IP 地址不在黑名单上
- 确保回复地址是有效的现有地址。
- 在“收件人”字段中使用收件人的完整真实姓名,而不仅仅是电子邮件地址(例如 ).
"John Smith" <[email protected]>
- 监控您的滥用帐户,例如 和 .这意味着 - 确保这些帐户存在,阅读发送给他们的内容,并对投诉采取行动。
[email protected]
[email protected]
- 最后,让退订变得非常容易。否则,您的用户将通过按下垃圾邮件按钮取消订阅,这将影响您的声誉。
有关此主题的更多信息,请参阅如何确保以编程方式发送的电子邮件不会自动标记为垃圾邮件。
确保提供所有邮件标头
如果邮件缺少“发件人”和“回复”等常见标题,某些垃圾邮件软件会拒绝邮件:
$headers = array("From: [email protected]",
"Reply-To: [email protected]",
"X-Mailer: PHP/" . PHP_VERSION
);
$headers = implode("\r\n", $headers);
mail($to, $subject, $message, $headers);
确保邮件头没有语法错误
无效的标头与没有标头一样糟糕。一个不正确的字符可能足以破坏您的电子邮件。仔细检查以确保您的语法正确,因为 PHP 不会为您捕获这些错误。
$headers = array("From [email protected]", // missing colon
"Reply To: [email protected]", // missing hyphen
"X-Mailer: "PHP"/" . PHP_VERSION // bad quotes
);
不要使用虚假发件人From:
虽然邮件必须具有 From: 发件人,但您不能只使用任何值。特别是,用户提供的发件人地址是阻止邮件的可靠方法:
$headers = array("From: $_POST[contactform_sender_email]"); // No!
原因:您的网站或发送邮件服务器未列入 SPF/DKIM 白名单,以假装对@hotmail或@gmail地址负责。它甚至可能静默地丢弃具有未配置的发件人域的邮件。From:
确保收件人值正确
有时,问题很简单,就像电子邮件收件人的值不正确一样。这可能是由于使用了不正确的变量。
$to = '[email protected]';
// other variables ....
mail($recipient, $subject, $message, $headers); // $recipient should be $to
测试这一点的另一种方法是将接收者值硬编码到函数调用中:mail()
mail('[email protected]', $subject, $message, $headers);
这可以应用于所有参数。mail()
发送到多个帐户
为了帮助排除电子邮件帐户问题,请将您的电子邮件发送到不同电子邮件提供商的多个电子邮件帐户。如果您的电子邮件未到达用户的 Gmail 帐户,请将相同的电子邮件发送到 Yahoo 帐户、Hotmail 帐户和常规 POP3 帐户(如 ISP 提供的电子邮件帐户)。
如果电子邮件到达所有或部分其他电子邮件帐户,则您知道您的代码正在发送电子邮件,但电子邮件帐户提供商可能出于某种原因阻止了它们。如果电子邮件未到达任何电子邮件帐户,则问题更有可能与您的代码有关。
确保代码与表单方法匹配
如果已将表单方法设置为 ,请确保用于查找表单值。如果您已将其设置为或根本没有设置它,请确保用于查找表单值。POST
$_POST
GET
$_GET
确保您的表单值指向正确的位置action
确保您的 form 属性包含指向您的 PHP 邮件代码的值。action
<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。(最好在 OR 或 MAY 中启用这些选项。php.ini
.user.ini
.htaccess
使用邮件测试服务进行检查
您可以使用各种交付和垃圾邮件检查服务来测试您的 MTA/Web 服务器设置。通常,您将邮件探测发送到:他们的地址,然后获得送达报告和更具体的故障或分析:
- mail-tester.example (免费/简单)
- glockapps.com(免费/$$$)
- senforensics.com(注册/$$$)
- mailtrap.io (pro/$$$)
- ultratools/.../emailTest(仅限免费/MX 检查)
- 各种:http://www.verticalresponse.com/blog/7-email-testing-delivery-tools/
使用其他邮件
PHP 的内置函数很方便,经常可以完成工作,但它有其缺点。幸运的是,有一些替代方案可以提供更多的功能和灵活性,包括处理上述许多问题:mail()
- 最受欢迎的是:PHPMailer
- 同样具有功能:SwiftMailer
- 甚至是较旧的 PEAR::Mail。
所有这些都可以与专业的SMTP服务器/服务提供商结合使用。(因为典型的 08/15 共享虚拟主机计划在电子邮件设置/可配置性方面是命中注定的。
如果您使用 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 = "[email protected]";
$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 = '[email protected]';
$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: [email protected]' . "\r\n" .
'Reply-To: [email protected]' . "\r\n" .
'X-Mailer: PHP/' . phpversion();
mail($to, $subject, $message, $headers);
还有一件事。该函数在 localhost 中不起作用。将您的代码上传到服务器并尝试。mail()
评论
$from = 'From: yoursite.com';
$from
如果只使用该函数,则需要完成配置文件。mail()
您需要打开邮件扩展,并设置等等,最重要的是,您的用户名和密码。否则,邮件就无法发送。此外,您可以使用该类进行发送。SMTP smtp_port
PHPMail
你可以使用 CodeIgniter 的配置电子邮件。例如,使用 SMTP(简单方式):
$config = Array(
'protocol' => 'smtp',
'smtp_host' => 'mail.domain.com', // Your SMTP host
'smtp_port' => 26, // Default port for SMTP
'smtp_user' => '[email protected]',
'smtp_pass' => 'password',
'mailtype' => 'html',
'charset' => 'iso-8859-1',
'wordwrap' => TRUE
);
$message = 'Your msg';
$this->load->library('email', $config);
$this->email->from('[email protected]', 'Title');
$this->email->to('[email protected]');
$this->email->subject('Header');
$this->email->message($message);
if($this->email->send())
{
// Conditional true
}
它对我有用!
评论
我认为这应该可以解决问题。我刚刚在正文中的变量中添加了一个并添加了串联,以将 PHP 与 HTML 分开。if(isset
<?php
$name = $_POST['name'];
$email = $_POST['email'];
$message = $_POST['message'];
$from = 'From: yoursite.com';
$to = '[email protected]';
$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>';
}
}
?>
分别尝试和一起尝试这两件事:
- 删除
if($_POST['submit']){}
- 删除(只是我的肠道)
$from
有几种可能性:
您面临服务器问题。服务器没有任何邮件服务器。所以你的邮件不起作用,因为你的代码很好,邮件是用类型处理的。
您没有获得发布的价值。尝试使用静态值编写代码。
使用 SMTP 邮件发送邮件...
- 始终尝试在邮件功能中发送标头。
- 如果您通过localhost发送邮件,请执行SMTP设置以发送邮件。
- 如果您通过服务器发送邮件,请检查您的服务器上是否启用了电子邮件发送功能。
试试这个
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>
';
}
}
$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>";
}
Add a mail header in the mail function:
$header = "From: [email protected]\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>';
}
It worked for me on 000webhost by doing the following:
$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";
Enter directly the email address when sending the email:
mail('[email protected]', $subject, $message, $headers)
Use and not .''
""
This code works, but the email was received with half an hour lag.
First of all, you might have too many parameters for the mail() function...
You are able to have of maximum of five, mail(to, subject, message, headers, parameters);
As far as the variable goes, that should automatically come from your webhost if your using the Linux cPanel. It automatically comes from your cPanel username and IP address.$from
$name = $_POST['name'];
$email = $_POST['email'];
$message = $_POST['message'];
$from = 'From: yoursite.com';
$to = '[email protected]';
$subject = 'Customer Inquiry';
$body = "From: $name\n E-Mail: $email\n Message:\n $message";
Also make sure you have the correct order of variables in your mail() function.
The in that order, or else there is a chance of it not working.mail($to, $subject, $message, etc.)
If you're having trouble sending mails with PHP, consider an alternative like PHPMailer or SwiftMailer.
I usually use SwiftMailer whenever I need to send mails with PHP.
Basic usage:
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('[email protected]' => 'Jane Doe'))
// The to address(es)
->setTo(array('[email protected]' => '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);
}
See the official documentation for more information on how to use SwiftMailer.
For anyone who finds this going forward, I would not recommend using . There's some answers that touch on this, but not the why of it.mail
PHP's function is not only opaque, it fully relies on whatever MTA you use (i.e. Sendmail) to do the work. will only tell you if the MTA failed to accept it (i.e. Sendmail was down when you tried to send). It cannot tell you if the mail was successful because it's handed it off. As such (as John Conde's answer details), you now get to fiddle with the logs of the MTA and hope that it tells you enough about the failure to fix it. If you're on a shared host or don't have access to the MTA logs, you're out of luck. Sadly, the default for most vanilla installs for Linux handle it this way.mail
mail
A mail library (PHPMailer, Zend Framework 2+, etc.), does something very different from . They open a socket directly to the receiving mail server and then send the SMTP mail commands directly over that socket. In other words, the class acts as its own MTA (note that you can tell the libraries to use to ultimately send the mail, but I would strongly recommend you not do that).mail
mail
This means you can then directly see the responses from the receiving server (in PHPMailer, for instance, you can turn on debugging output). No more guessing if a mail failed to send or why.
If you're using SMTP (i.e. you're calling ), you can get a detailed transcript of the SMTP conversation using the property.
isSMTP()
SMTPDebug
Set this option by including a line like this in your script:
$mail->SMTPDebug = 2;
You also get the benefit of a better interface. With you have to set up all your headers, attachments, etc. With a library, you have a dedicated function to do that. It also means the function is doing all the tricky parts (like headers).mail
Mostly the function is disabled in shared hosting.
A better option is to use SMTP. The best option would be Gmail or SendGrid.mail()
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();
}
?>
评论
If you are running this code on a local server (i.e your computer for development purposes) it won't send the email to the recipient. It will create a file in a folder named ..txt
mailoutput
In the case if you are using a free hosing service, like or , those service providers disable the function to prevent unintended uses of email spoofing, spamming, etc. I prefer you to contact them to see whether they support this feature.000webhost
hostinger
mail()
If you are sure that the service provider supports the mail() function, you can check this PHP manual for further reference,
To check weather your hosting service support the mail() function, try running this code (remember to change the recipient email address):
<?php
$to = '[email protected]';
$subject = 'the subject';
$message = 'hello';
$headers = 'From: [email protected]' . "\r\n" .
'Reply-To: [email protected]' . "\r\n" .
'X-Mailer: PHP/' . phpversion();
mail($to, $subject, $message, $headers);
?>
This will only affect a small handful of users, but I'd like it documented for that small handful. This member of that small handful spent 6 hours troubleshooting a working PHP mail script because of this issue.
If you're going to a university that runs XAMPP from www.AceITLab.com, you should know what our professor didn't tell us: The AceITLab firewall (not the Windows firewall) blocks MercuryMail in XAMPP. You'll have to use an alternative mail client, pear is working for us. You'll have to send to a Gmail account with low security settings.
Yes, I know, this is totally useless for real world email. However, from what I've seen, academic settings and the real world often have precious little in common.
评论
For those who do not want to use external mailers and want to mail() on a dedicated Linux server.
The way, how PHP mails, is described in in section .php.ini
[mail function]
Parameter describes how sendmail is called. The default value is , so if you get a working in the Linux console - you will be done. You could also add to debug and be sure mail() is really called.sendmail-path
sendmail -t -i
sendmail -t -i < message.txt
mail.log
Different MTAs can implement . They just make a symbolic link to their binaries on that name. For example, in Debian the default is Postfix. Configure your MTA to send mail and test it from the console with . File should contain all headers of a message and a body, destination address for the envelope will be taken from the header. Example:sendmail
sendmail -v -t -i < message.txt
message.txt
To:
From: [email protected]
To: [email protected]
Subject: Test mail via sendmail.
Text body.
I prefer to use ssmtp as MTA because it is simple and does not require running a daemon with opened ports. ssmtp fits only for sending mail from localhost. It also can send authenticated email via your account on a public mail service. Install ssmtp and edit configuration file . To be able also to receive local system mail to Unix accounts (alerts to root from cron jobs, for example) configure file./etc/ssmtp/ssmtp.conf
/etc/ssmtp/revaliases
Here is my configuration for my account on Yandex mail:
[email protected]
mailhub=smtp.yandex.ru:465
FromLineOverride=YES
UseTLS=YES
[email protected]
AuthPass=password
Make sure you have Sendmail installed in your server.
If you have checked your code and verified that there is nothing wrong there, go to /var/mail and check whether that folder is empty.
If it is empty, you will need to do a:
sudo apt-get install sendmail
if you are on an Ubuntu server.
评论
也许问题出在邮件服务器的配置上。为了避免此类问题,或者您不必担心邮件服务器问题,我建议您使用 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 = '[email protected]';
$mail->Password = 'contrasenia';
$mail->SMTPSecure = 'ssl';
$mail->Port = 465;
// Recipients
$mail->setFrom('[email protected]', 'my name');
$mail->addAddress('[email protected]');
// 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;
}
评论
您可以通过以下方式查看错误:
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 = '[email protected]'; // SMTP username
$mail->Password = 'password'; // SMTP password
$mail->SMTPSecure = 'tls'; // Enable encryption, 'ssl' also accepted
$mail->From = '[email protected]';
$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';
?>
评论
SMTPDebug = 0
没有帮助。普通的“密码”也不适用于 GMail。这个答案在这里没有多大贡献。
如果您被困在Hostgator上托管的应用程序,这就是解决我问题的方法。非常感谢发布详细解决方案的人。如果有一天链接离线,你有摘要:
- 在服务器中查找 sendmail 路径。检查它的一种简单方法是在只有您才能访问的页面中临时编写以下代码,以读取生成的信息:.打开此页面,然后查找 .(然后,别忘了删除此代码!
<?php phpinfo(); ?>
sendmail path
- 问题和修复:如果您的 sendmail 路径仅显示 ,请编辑服务器的路径并添加以下行:
-t -i
php.ini
sendmail_path = /usr/sbin/sendmail -t -i;
但是,在能够使用PHP功能发送邮件后,我了解到它发送未经身份验证的电子邮件,这造成了另一个问题。这些电子邮件都落在了我的 Hotmail 的垃圾邮件箱中,有些电子邮件从未送达,我想这与它们未经身份验证有关。毕竟,这就是我决定从 SMTP 切换到 SMTP 的原因。mail()
mail()
PHPMailer
$headers的这一部分中的“发件人:”$email地址可能有问题:
From: \"$name\" <$email>
要尝试一下,请发送一封没有标题部分的电子邮件,例如:
mail('[email protected]', $subject, $message);
如果是这种情况,请尝试使用已在您尝试从中发送邮件的系统上创建的电子邮件帐户。
<?php
$to = '[email protected]';
$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 <[email protected]>".$eol;
$headers .= "Return-Path: Name <[email protected]>".$eol;
$headers .= "From: Name <[email protected]>".$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 电子邮件。
例上面的示例将向 [email protected] 发送 HTML 电子邮件。您可以对这个程序进行编码,使其应该从用户那里接收所有内容,然后它应该发送电子邮件。
评论
您可以使用它完美地工作,下面是一个代码示例: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 = "[email protected]";//the email which will send the email
$mail->Password = "XXXXXXXXXX";//the password
$mail->IsHTML(true);
$mail->AddAddress($to, "recipient-name");
$mail->SetFrom("[email protected]", "from-name");
$mail->AddReplyTo("[email protected]", "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();
}
我遇到了这个问题,发现剥离标题可以帮助我发送邮件。 所以这个:
$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的新行。 我很欣赏这不是纯粹编码者的方法,但它适用于我需要它的东西。
就我而言,这封电子邮件发送得很好,但被接收了,因为整个消息都在一行超过 998 个 caracters 中。我需要用以下行制作最大长度为 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.
有很多方法可以失败,但就我而言,是这样的:mail()
我已经在我的服务器上安装了,但没有配置或运行本地 MTA - 如果我在命令行上键入,我会收到错误”sendmail
sendmail
sendmail: can't connect to remote host (127.0.0.1): Connection refused
"
如果您得到类似的东西,则说明您没有安装/配置 MTA,以下详细信息可能会对您有所帮助:
如果您收到上述错误,您可以安装本地 MTA,然后一切正常,但就我而言,我不想运行本地 MTA,因为我想使用 .msmtp
mail()
返回 FALSE,但没有错误消息,我的 php.log 或任何其他日志中都没有错误,它只是静默地失败了。
我配置了以下内容以覆盖 和 use 的 使用(使用兼容的参数):php.ini
sendmail
msmtp
sendmail
sendmail_path = /usr/bin/msmtp
但是,即使我可以手动运行并发送电子邮件,更改此参数也无法正常工作。mail()
msmtp
在我看来,当您将其更改为其他内容时,PHP会忽略它,并且它继续执行。mail()
sendmail_path
sendmail
在没有安装本地 MTA 的情况下,我唯一可以开始工作的方法就是:mail()
sendmail
- 在注释中
php.ini
sendmail_path
- 创建一个符号链接,如下所示:
msmtp
ln /usr/bin/msmtp /usr/sbin/sendmail
我一这样做,就立即开始工作。mail()
我还不能证明这一点,但我的直觉是 php 中有一个与相关的错误,它基本上忽略它并无论如何运行。sendmail_path
sendmail
评论
$from
mail()