这将是对我们一直在这里使用的网站更改请求表单演示的延续。如果您需要赶上进度,首先我 谈论了它,然后我 构建了它,然后我 录制了它,然后我 保护了它。在所有这些过程中,最终结果一直是一封无聊的纯文本电子邮件,发送到单个电子邮件地址。
我们将改进该输出,并将电子邮件变成外观更漂亮的 HTML 格式电子邮件。
它与文本电子邮件没什么不同
通过 PHP 发送 HTML 电子邮件使用完全相同的mail函数作为文本电子邮件
mail($to, $subject, $message, $headers);
最后一个参数,标题,对于该函数是可选的,但对于发送 HTML 电子邮件是必需的,因为这是我们能够传递 Content-Type 声明以告知电子邮件客户端将电子邮件解析为 HTML 的地方。
实际上,标题区域使我们有机会执行许多重要的电子邮件功能。如果需要,我们可以在此处设置 From: 和 Reply To: 设置,以及 CC 和 BCC 其他收件人(嘿,为自己添加一个 CC 复选框将是一个很酷的功能!)。以下是用于新的改进的 HTML-Sendin' 网站更改请求表单的代码
$to = '[email protected]';
$subject = 'Website Change Request';
$headers = "From: " . strip_tags($_POST['req-email']) . "\r\n";
$headers .= "Reply-To: ". strip_tags($_POST['req-email']) . "\r\n";
$headers .= "CC: [email protected]\r\n";
$headers .= "MIME-Version: 1.0\r\n";
$headers .= "Content-Type: text/html; charset=ISO-8859-1\r\n";
现在我们可以使用 HTML 标签
message 参数(我们传递给的包含我们电子邮件正文的大字符串mail函数),现在可以在其中包含 HTML 标签。例如
$message = '<html><body>';
$message .= '<h1>Hello, World!</h1>';
$message .= '</body></html>';
以下是一整套代码,用于创建如上所示的数据表
$message = '<html><body>';
$message .= '<img src="//css-tricks.org.cn/examples/WebsiteChangeRequestForm/images/wcrf-header.png" alt="Website Change Request" />';
$message .= '<table rules="all" style="border-color: #666;" cellpadding="10">';
$message .= "<tr style='background: #eee;'><td><strong>Name:</strong> </td><td>" . strip_tags($_POST['req-name']) . "</td></tr>";
$message .= "<tr><td><strong>Email:</strong> </td><td>" . strip_tags($_POST['req-email']) . "</td></tr>";
$message .= "<tr><td><strong>Type of Change:</strong> </td><td>" . strip_tags($_POST['typeOfChange']) . "</td></tr>";
$message .= "<tr><td><strong>Urgency:</strong> </td><td>" . strip_tags($_POST['urgency']) . "</td></tr>";
$message .= "<tr><td><strong>URL To Change (main):</strong> </td><td>" . $_POST['URL-main'] . "</td></tr>";
$addURLS = $_POST['addURLS'];
if (($addURLS) != '') {
$message .= "<tr><td><strong>URL To Change (additional):</strong> </td><td>" . strip_tags($addURLS) . "</td></tr>";
}
$curText = htmlentities($_POST['curText']);
if (($curText) != '') {
$message .= "<tr><td><strong>CURRENT Content:</strong> </td><td>" . $curText . "</td></tr>";
}
$message .= "<tr><td><strong>NEW Content:</strong> </td><td>" . htmlentities($_POST['newText']) . "</td></tr>";
$message .= "</table>";
$message .= "</body></html>";
我认为这看起来好多了。由于这封电子邮件(理论上)是直接发给您的,了解它将被格式化为易于阅读的格式是否很好?
顾虑
有些人绝对讨厌 HTML 电子邮件。首先,它可能存在安全风险,因为在某些电子邮件客户端中可能在其中运行 JavaScript,这可能有问题。HTML 电子邮件还习惯于更容易被垃圾邮件过滤器捕获。我认为这在这里不太令人担忧,因为这封电子邮件基本上是您为自己创建的。
演示
我更新了演示和下载以使用新的 HTML 电子邮件格式。
这个表单可能还会出现一两个演示。至少我想在发送电子邮件之前做一个关于将数据写入数据库的演示。电子邮件可能是如此脆弱,因此首先将数据保存到数据库无疑是一个明智之举。
对于 HTML 电子邮件,我会额外使用一个包含 HTML 和必要的变量标记的模板文件。这样,我的 HTML 与我的 PHP 分开,这使得对电子邮件外观进行简单更改变得更加容易。
我无法告诉你,我修改了 PHP 变量或 echo 语句中的 HTML 多次,但忘记在双引号前添加斜杠,然后最终出现了一个令人讨厌的错误。
使用单引号 - 对我来说总是没问题
我也是
heredoc 效果更好,虽然把它放在一个单独的文件中很好,但只需为变量设置一些简单的替换字符串即可。
https://php.ac.cn/manual/en/language.types.string.php
我最初对 nowdoc 很兴奋,但它还没有发布。以这种速度,它直到 PHP 6 才会稳定。
我想通过 php 发送一封电子邮件,但它不起作用,我不知道该怎么办,请帮忙。
非常棒的文章,我上周实际上只是在向别人询问关于 HTML 电子邮件的提示。谢谢!
很棒,Chris。只是一点小补充:你真的应该看看 PHPMailer 库:它比“正常的”mail() 函数更好用。
你可以简单地创建一个新实例
$var = new phpMailer();
将其设置为 HTML
$var->useHTML(true);
然后添加正文
$var->body(); // 邮件内容
发送!
$var->send();
(这只是从我的脑海中得出的,函数名称可能不同)
我曾经使用与 Chris 类似的脚本,但现在我使用 Zend 的验证类来验证电子邮件,并使用邮件类来发送电子邮件,它为我处理所有事情,包括错误处理等等。你甚至可以指定一个纯文本版本,这非常简单。
这是它的简短用法。
require_once ‘Zend/Mail.php’;
$mail=new Zend_Mail();
require_once ‘Zend/Validate/EmailAddress.php’;
$validator=new Zend_Validate_EmailAddress();
if($validator->isValid($_POST[’email’]))
{
// 纯文本版本,所以去除标签
$mail->setBodyText(strip_tags($_POST[‘message’]));
// html 版本
$mail->setBodyHtml($_POST[‘message’]);
$mail->setFrom($_POST[’email’],’发件人姓名’);
$mail->addTo(‘[email protected]’,”收件人姓名”);
$mail->setSubject(‘主题’);
// 发送电子邮件
$mail->send();
}
else
{
foreach($validator->getMessages() as $errorMessage)
{
echo “$errorMessage”;
}
}
错误会告诉用户电子邮件无效的确切原因。您可以使用 strip_tags 函数去除您不想要的标签,例如 javascript 标签和/或链接。
Robert 我喜欢你的想法,但不确定如何实现,如果你有一个 html 格式的电子邮件模板,你如何在 php 文件中包含它并向它传递变量?
你能提供一些链接/指南吗?
我使用的函数只是加载一个文件,然后用指定的结果(例如 {TITLE} => $foo 或 {TITLE} => “我的主页”)替换该文件中的变量(在我的情况下,变量用方括号括起来,例如 {TITLE} 或 {BODY})。
由于我倾向于输出为 $variableName = callToMyFunction(“filename.tmpl”); $variableName 已经包含了整个 HTML 片段……就这么简单。
赞扬你使用“its”而不是“it’s”作为你演示的重点。
它是许多其他聪明开发人员的克星。
http://tr.im/itsits
呃,你会收到很多垃圾邮件吧?
strip_tags 应该清理 From: 地址等等,对吧?错!记住 SMTP 的工作原理,\n\r 可以注入标头,你需要过滤掉它们。一行上的单个点可以结束 DATA 事务。你需要过滤掉它们。
我建议你阅读手册页上的说明:-
http://uk.php.net/manual/en/function.mail.php
很棒的文章。我正要制作一个联系表单,所以这确实很有帮助。
我同意 Marco 的观点。人们应该考虑使用 PHPMailer 或 Swift 等第三方库,而不是使用 php 中的纯 mail 函数,尤其是在你想要使用 SMTP 身份验证时。但无论如何,对于初学者来说这是一个很好的例子。
早三天就能用上就好了。:)
很棒的文章!不过我有一个问题,你如何设置才能在同一邮件中发送 HTML 邮件和纯文本?我知道可以做到,只是从来没有弄明白。
查看这篇教程 http://www.sitepoint.com/print/advanced-email-php/ 或直接使用 phpmailer。
您必须设置变量 $mail->Body(html 文本)和 $mail->AltBody(纯文本)才能发送多部分邮件。
好文章。但是,它容易受到 邮件注入 的影响。
这里有 strip_tags
$headers = “From: ” . strip_tags($_POST[‘req-email’])
没有多大帮助。
它只去除 html 标签,不会去除 \r\n。
您必须过滤 req-email 中的 \r\n。
如果您有该区域的替换代码,我将不胜感激,我会更新示例并下载。
像这样
$req-email = $_POST[‘req-email’];
$req-email = preg_replace(‘=((||0x0A/%0A|0x0D/%0D|\\n|\\r)\S).*=i’, null, $req-email);
$headers = “From: $req-email\r\n”;
$headers .= “Reply-To: $req-email\r\n”;
preg_replace(‘/[^a-zA-Z0-9\._\-@]/’,”,$_POST[‘req-email’])
将替换电子邮件地址中不允许的任何字符。但是,我仍然建议进行更全面的 preg_match 来确定结构是否为正确的电子邮件格式。
我无法让这两个代码起作用。我复制粘贴并将愚蠢的 wordpress 卷曲引号转换为直引号,但没有效果。也许发布它们时有些东西乱了。我对 RegEx 不太了解,无法自行调试,但如果我学会了,我会尝试将其集成。
我实际上刚刚发布了类似的内容,除了我介绍了发送带有 HTML 和纯文本版本的邮件。
我还对电子邮件地址进行了验证,以确保不会出现任何爆炸。那里的正则表达式有效。
链接
好文章!
优秀。
记录一下,我偷了这个并实现了它,因此 From: 业务现在应该很干净、安全。
我同意其他评论,并建议使用 phpMailer。MIME 邮件看起来不错,但如果收件人没有 MIME 或选择不查看 MIME 会怎么样?我认为最佳做法是使用 MIME 和文本版本的电子邮件,phpMailer 简化了此过程。
但是,Microsoft 回溯了 HTML 邮件,现在使用 Word 作为邮件的渲染工具,这限制性更强。如果大量的电子邮件收件人是企业人士,您最好阅读 Campaign Monitor 对此主题的思考。
就我个人而言,我现在已经退回到纯文本电子邮件,因为这是开发人员最初的意图。邮件更小,更有可能正确渲染,如果我 *真的* 需要给某人留下深刻印象,我只需链接到广播的网页版本。所以 PHP 的 mail 函数和一个替换模板变量的正则表达式对我有用。
不要忘记这里的上下文。在他的特定示例中,他正在为自己生成 HTML 邮件,因此没有理由为所有接收平台编写代码。
我一直在做一些我认为可以有效防止您的邮件客户端将来自您网站的邮件标记为垃圾邮件的操作。
只需将“From”标头设置为类似‘[email protected]’的内容,然后将“Reply-To”标头设置为用户的电子邮件,就像平常一样。
现在,您只需将‘[email protected]’添加到您的联系人,您将始终收到邮件,但仍然可以点击回复,邮件将发送到正确的电子邮件地址。
切勿将 from-header 设置为用户的电子邮件地址!您可能会因 SPF (http://en.wikipedia.org/wiki/Sender_Policy_Framework) 而被垃圾邮件过滤器屏蔽。最糟糕的是您的 ip 被列入黑名单。
http://www.html-form-guide.com/email-form/php-script-not-sending-email.html
上面链接的文章对此解释得很好。简而言之,是的,将“From”设置为服务器允许发送的域中的地址。将“Reply-To”设置为您想要的任何内容——例如表单提交者的地址。
还没看完,但我知道它会很棒。提前感谢 Chris!
到目前为止,我只使用纯文本版本,但现在是改变的时候了;)
抱歉,但我真的不明白这里有什么新东西?HTML 邮件已经存在很长时间了……
此外,在您的邮件中,您有一个来自您域的图像(“<img src=’https://css-tricks.org.cn/ex…'”),您应该注意并警告人们它会被大多数现代客户端屏蔽。
让人担忧的是,人们在编写教程,但似乎无法实际编写出像样的代码。我一直以为(或者至少希望)所有头脑清醒的程序员现在都对电子邮件标头有相当的了解……无论如何,我想实际的教程对许多初学者来说会非常有用——尽管向他们展示如何制作易受垃圾邮件攻击的表单 !== 合理。
嗨 Chris,
不错的文章,但我认为您也应该提到不应该在电子邮件模板中使用 div 和浮动,而应该使用表格和内联样式。我知道这就是您使用的方式,但我只是说您应该告诉读者为什么这样做……这是因为我们所有的电子邮件客户端仍然停留在石器时代:)
感谢这条评论。我一直努力用 div 格式化我的电子邮件。Chris,感谢您的帖子。
很高兴能帮到您:)
$message = '';
$message .= '';
$message .= '';
$message .= "Name: " . strip_tags($_POST['req-name']) . "";
$message .= "Email: " . strip_tags($_POST['req-email']) . "";
$message .= "Type of Change: " . strip_tags($_POST['typeOfChange']) . "";
$message .= "Urgency: " . strip_tags($_POST['urgency']) . "";
$message .= "URL To Change (main): " . $_POST['URL-main'] . "";
$addURLS = $_POST['addURLS'];
if (($addURLS) != '') {
$message .= "URL To Change (additional): " . strip_tags($addURLS) . "";
}
$curText = htmlentities($_POST['curText']);
if (($curText) != '') {
$message .= "CURRENT Content: " . $curText . "";
}
$message .= "NEW Content: " . htmlentities($_POST['newText']) . "";
$message .= "";
$message .= "";
与其这样做……不如试试 heredoc
$name = strip_tags($_POST['req-name']) ;
$email = strip_tags($_POST['req-email']);
$typeChange = strip_tags($_POST['typeOfChange']);
$urgency = strip_tags($_POST['urgency']);
$urlMail = $_POST['URL-main'];
$addURLS = ($_POST['addURLS'] != NULL) : "URL To Change (additional): " . strip_tags($_POST['addURLS']) . "";
$curText = (htmlentities($_POST['curText']) == NULL) : "CURRENT Content: " . htmlentities($_POST['curText']) . "" ;
$newText = htmlentities($_POST['newText']);
$message = <<<EOD
Name: $name";
Email: $email
Type of Change: $typeChange
Urgency: $urgency
URL To Change (main): $urlMail
$addURLS
$curText
NEW Content: $newText";
EOD;
保存这些内容,更易于阅读和使用……。
嗨 Chris,
很好的解释。我必须试一试,希望它对我有用:)
谢谢
Sankar
为了提高网页可访问性,您可以考虑将 accesskey 属性添加到 label 标签中。
我为此使用 phpmailer,效果很好。我建议以组合格式(纯文本/HTML)发送电子邮件。
您是如何让它起作用的?我做不到。
我更改了联系信息,但仍然没有效果。有什么想法吗?
我认为 URL 字段有问题。我知道 URL 是什么以及如何格式化它,但我们有多少客户知道这一点?我认为该字段太严格了,因为它要求 http 和 www 来验证该字段。
哇,我刚用 PHP 处理 HTML 邮件时遇到了一些问题,然后我来到了这个网站。很棒的工作。您帮助我解决了一些问题!
对于那些推荐PHPMailer的人,看看SwiftMailer。它提供了相同的功能,但在我看来,它拥有更完善的类设计。
Leeeeeeeerrrrrrrrrroooooyyyyyyyyyyyy Jeeeeennnnnnnkkkkkiiiiiiiinnnnnssssss
与本文无关,只是想说一下!
好文章,这是一个非常简单的HTML邮件格式化方法!
另一个检查电子邮件的函数
http://www.phpinform.com/2009/06/17/another-function-to-check-email/
我学到一个小技巧。如果你不想把你的HTML分成一堆变量,你可以这样做...
$html = <<< newsletter
$message…
newsletter;
mail($email, $subject, $html, $headers);
有没有PHP4版本?邮件只有在运行PHP5时才能成功发送。
那么如何在$body中添加PHP内容呢?
我将在另一个页面中从表单获取消息标题,并将它通过POST发送到“send_newsletter”页面。
然后需要在发出的电子邮件中显示我在另一个页面中编写的标题。
如何做到这一点?
谢谢
嗨,克里斯,
你这里有一个很棒的表单。
我一直关注着它,从第一个版本开始,这是一个非常酷的结果。
我在自定义过程中发现了一个小错误。
在“index.php”的第135行,你在$message的第二行忘记了一个点(“.”),这会导致它不包含在发送的消息中。
而且第二个$message也是=而不是.=。
至于其他部分...很棒的表单,是我见过的最好的。
——
TeMc
很棒,抓住了,谢谢。我已经更新了文章和下载内容。
嘿,CSS-Tricks,
前几天我用这个表单做了一个自由职业者的网站,发现自己需要定制邮件输出,所以我想分享我的做法。
在所有单行字段(如姓名、地址等)的HTML电子邮件中,这个
以及文本区域的
stripslashes可以去掉引号中令人讨厌的斜杠/ 'es,这些斜杠/ 'es 会根据你的服务器和框架设置自动添加。
nl2br可以方便地在表单文本区域中保留换行符。
对于非文本区域,trim函数可以去掉开头和结尾的换行符和空格。
——
我的2美分,
Krinkle
我正在使用php pear发送邮件,用这种方式,如何发送HTML格式化的邮件?我已经尝试了很多方法,但都失败了。你能帮我吗?
嗨,我刚接触web开发,我正在寻找一个代码,通过它我可以发送邮件到电子邮件地址,并使用特定的格式。
当我在邮件文本中使用HTML标签时,这些标签在邮件中显示为文本。
请帮帮我,告诉我如何使用格式发送邮件。
此致
vikas siwach
完美!
谢谢
嗨 Chris,
不错的教程。你能确认一下,使用php邮件函数发送邮件时,邮件正文的字符数或邮件正文中表格的行数是否有限制吗?
如果有,如何增加限制?
需要将消息表格化吗?(刚开始学习发送邮件。)
非常感谢你,克里斯,你做得太棒了!:)
嗨,克里斯,
我发现两个错误,并不重要,只对接收邮件的开发者或
开发者和网站所有者之间的中间人(接收这些请求)可见。
它们不在注释标签中,也不在变量名中。
第28行
IP-Adress: {$ip} \n
// 地址
第173行
$subject = ‘Website Change Reqest’;
// 请求
完全丢失了。我不确定你们怎么样,但我需要它并且一直在使用它。此外,我更喜欢phpmailer。没有必要浪费你的时间来编写一个函数,你可以花5分钟使用phpmailer中的一套完善的类。只是我的一点想法,时间对于老年人来说太宝贵了,所以不能再浪费它了。