我有一个相当简单的功能来发送电子邮件。\n我开始实现电子邮件的翻译版本,随之而来的是特殊字符,例如 \xc3\xa9 和 \xc3\xb3。每当我的电子邮件主题中有这些内容时,该电子邮件就会在我的 amavis 中引起 BAD_HEADER 错误,从而造成麻烦。
\n\n显然它不是 8 位编码的,这乍一看是有道理的。但是,我在网络上找不到任何指南或解释如何正确编码主题。
\n\n只是为了好玩,我尝试了 é 而不是 \xc3\xa9,当然问题得到了解决。但与此同时,电子邮件的主题中带有 é,而不是 \xc3\xa9。
\n\n这是我目前拥有的脚本:
\n\nfunction sendEmail() {\n\n // Build HTML version\n ob_start();\n include(\'emailhtml.php\');\n $msgHTML = ob_get_contents();\n ob_end_clean();\n\n // Build TXT version\n ob_start();\n include(\'email.php\');\n $msgTxt = ob_get_contents();\n ob_end_clean();\n\n\n // Subject & headers\n $subject = "\xc3\xa1\xc3\xa9\xc3\xad\xc3\xb3\xc3\xba";\n $boundary = md5(uniqid(rand())); \n $headers = array();\n $headers[] = "MIME-Version: 1.0";\n $headers[] = "Content-Type: multipart/alternative; boundary = ".$boundary;\n $headers[] = "From: ".$from." <".$from_email.">";\n $headers[] = "Reply-To: ".$reply2_email;\n\n // Plain text version of message\n $body = "--$boundary\\r\\n" .\n "Content-Type: text/plain; charset=UTF-8\\r\\n" .\n "Content-Transfer-Encoding: base64\\r\\n\\r\\n";\n $body .= chunk_split(base64_encode($msgTxt));\n\n // HTML version of message\n $body .= "--$boundary\\r\\n" .\n "Content-Type: text/html; charset=UTF-8\\r\\n" .\n "Content-Transfer-Encoding: base64\\r\\n\\r\\n";\n $body .= chunk_split(base64_encode($msgHTML));\n $body .= "--$boundary--\\r\\n";\n\n // BAM! Shoot it off...\n mail($receiver, $subject, $body, implode("\\r\\n", $headers));\n}\nRun Code Online (Sandbox Code Playgroud)\n
对邮件标头进行编码
\n\n如果其中包含字符集之外的任何字符,则Subject: header需要对其进行编码ASCII。
编码类型
\n\n您可以使用两种编码:Quoted Printable或Base64。内容的典型编码主题标头\xc3\xa1\xc3\xa9\xc3\xad\xc3\xb3\xc3\xba如下所示:
// Using Quoted Printable encoding:\nSubject: =?ISO-8859-1?Q?=C3=A1=C3=A9=C3=AD=C3=B3=C3=BA?=\n\n// Using Base64 encoding:\nSubject: =?ISO-8859-1?B?w6HDqcOtw7PDug==?=\nRun Code Online (Sandbox Code Playgroud)\n\n首选方式
\n\n如果您是使用多字节字符串函数PHP编译的,则应该使用mb_encode_mimeheader():
$subject = "\xc3\xa1\xc3\xa9\xc3\xad\xc3\xb3\xc3\xba";\n$encoded_subject = mb_encode_mimeheader($subject);\nprint $encoded_subject;\n// output: =?UTF-8?B?w4PCocODwqnDg8Ktw4PCs8ODwro=?=\nRun Code Online (Sandbox Code Playgroud)\n\n手动方式
\n\n如果你不能使用mb_encode_mimeheader()你可以使用一些第三方PHP库,或者创建你自己的编码函数。
$subject = "\xc3\xa1\xc3\xa9\xc3\xad\xc3\xb3\xc3\xba";\n$encoded_subject = "=?ISO-8859-1?Q?" . quoted_printable_encode($subject) . "?=";\nprint $encoded_subject;\n// Output: =?ISO-8859-1?Q?=C3=A1=C3=A9=C3=AD=C3=B3=C3=BA?=\nRun Code Online (Sandbox Code Playgroud)\n\n血淋淋的细节
\n\n正确进行 MIME 编码并非易事。要了解有关它的所有内容,您应该从学习RFC 2047和RFC 2045开始
\n