PHP 邮件格式问题 - 为啥 CRLF 标题行结尾会破坏 Outlook 中的 HTML 电子邮件?

Posted

技术标签:

【中文标题】PHP 邮件格式问题 - 为啥 CRLF 标题行结尾会破坏 Outlook 中的 HTML 电子邮件?【英文标题】:PHP mail formatting issue - Why do CRLF header line endings break HTML email in Outlook?PHP 邮件格式问题 - 为什么 CRLF 标题行结尾会破坏 Outlook 中的 HTML 电子邮件? 【发布时间】:2011-03-27 20:08:26 【问题描述】:

我正在使用 php 原生 mail() 函数发送 html 电子邮件,但在用户最常见的电子邮件客户端 - Outlook 2007 中存在格式问题(除了一些其他电子邮件clients) - 所有的 html 标签都被暴露出来,所以对于非 web 开发者来说,这看起来像是胡言乱语。

我发送 HTML 电子邮件的方式与 PHP manual 演示它的方式相同。示例:

$message  = get_HTML_email_with_valid_formatting();
$headers  = "MIME-Version: 1.0\r\n";
$headers .= "Content-Type: text/html; charset=UTF-8\r\n";
$headers .= "From: example.com <info@example.com>\r\n";
$headers .= "Reply-To: donotreply@example.com\r\n";
mail('me@example.com', 'test', $message, $headers);

因为测试各种电子邮件客户端很困难,所以我注册了http://litmusapp.com/,因此我可以看到 47 个不同电子邮件客户端中的电子邮件截图。大多数都可以(例如 gmail、thunderbird、Lotus Notes),但所有不同版本的 Outlook 都不好。

为了解决格式问题,我做了以下操作:

    删除$headers = "MIME-Version: 1.0\r\n"; 邮件标头。 确保我只以“\n”而不是“\r\n”结束我的标题。

有谁知道为什么我在不符合手册的情况下使用 HTML 电子邮件会获得更好的结果?

信息:

我在 RHEL 5.5 上使用 postfix 版本 2.3.3。 PHP 版本 5.3.2

【问题讨论】:

“我正在使用 PHP 本机 mail() 函数来发送 HTML 电子邮件” - 嗯,这是你的问题* ;-) 你有没有考虑过使用类似的东西,例如swiftmailer.org ? | * 也许不是mail()函数本身,而是mail()、一些字符串连接&试图同时解决协议和应用程序级问题的组合。 【参考方案1】:

如果你使用postfixsendmail_path = "tr -d '\r'|sendmail -t -i"放到php.ini中。

【讨论】:

【参考方案2】:

您有 2 个解决方案:

    将具有“sendmail_fix_line_endings”的 Postfix 升级到 +2.9(终于!!!)参见:Postfix documentation 安装 Sendmail(工作正常!)

我有一个带有 LAMP 堆栈的 VMware 映像。为了发送电子邮件,我最终决定:

安装 Sendmail 使用我的 ISP 的 smtp(因为它只是一个开发盒)。

对于 sendmail 部分,您可以按照以下方式操作:http://www.geoffke.be/nieuws/13/

重要提示:一些网络托管商可能只使用稳定的软件包,这意味着您可以拥有... 2.9 之前的 Postfix!示例:http://packages.debian.org/search?keywords=postfix

【讨论】:

【参考方案3】:

我怀疑这是我的 Postfix 版本 - 版本 2.3.3 已有 5 年历史,也许它正在将 LF 转换为 CRLF,但看到我已经有 CRLF,我想我正在发送 CRCRLF邮件客户端。

很遗憾,我无法升级 Postfix。因此,目前我已将代码转换为使用可配置变量作为行尾,以便将来轻松更改:

$eol = "\n";
$message  = get_HTML_email_with_valid_formatting();
$headers  = "MIME-Version: 1.0".$eol;
$headers .= "Content-Type: text/html; charset=UTF-8".$eol;
$headers .= "From: example.com <info@example.com>".$eol;
$headers .= "Reply-To: donotreply@example.com".$eol;
mail('me@example.com', 'test', $message, $headers);

【讨论】:

【参考方案4】:

电子邮件被解释为 text/plain 而不是预期的 html。原因是 text/html 是多部分子类型,因此需要边界声明。

您的代码缺少 标题边界 声明:

$message  = get_HTML_email_with_valid_formatting();
$headers  = "MIME-Version: 1.0\r\n";
$headers .= "--$boundary\r\n"."Content-Type: text/html; charset=ISO-8859-1\r\n";
$headers .= "From: example.com <info@example.com>\r\n";
$headers .= "Reply-To: donotreply@example.com\r\n";
mail('me@example.com', 'test', $message, $headers);

查看有关 MIME 和多部分消息的 wiki: http://en.wikipedia.org/wiki/MIME#Multipart_messages

【讨论】:

...这样结果至少是一致的,所有电子邮件客户端都会显示垃圾邮件? 感谢您的评论。我的印象是 HTML 电子邮件并不严格需要是多部分的。即拥有文本版本是一种很好的做法,但不是必需的。

以上是关于PHP 邮件格式问题 - 为啥 CRLF 标题行结尾会破坏 Outlook 中的 HTML 电子邮件?的主要内容,如果未能解决你的问题,请参考以下文章

为啥这个 PHP 电子邮件脚本不会发送到我的 Yahoo 电子邮件?

为啥我的 php 联系表发送空白电子邮件? [复制]

为啥php邮件功能在xampp中不起作用

将静态图像添加到 php 邮件系统时,为啥会出现“意外 CID”错误?

从 php 中的文本输入中获取 CRLF

为啥我的 php 没有将我的联系表单输入发送到我的电子邮件?