想要将以下原始邮件转换为正常的UTF-8文本:
=?utf-8?Q?Schuker_hat_sich_vom_ = C3 = 9Cbungsabend_(01.01.2012)_abgem?= =?utf-8?Q?eldet?=
真实的文字是:
Schuker hat sichvomÜbungsabend(01.01.2012)abgemeldet
我的第一种转换方法:
$mime = '=?utf-8?Q?Schuker_hat_sich_vom_=C3=9Cbungsabend_(01.01.2012)_abgem?= =?utf-8?Q?eldet?=';
mb_internal_encoding("UTF-8");
echo mb_decode_mimeheader($mime);
这给了我以下结果:
Schuker_hat_sich_vom_Übungsabend_(01.01.2012)_abgemeldet
(问题在这里:我做错了什么?为什么会出现这些下划线?)
我转换它的第二种方法:
$mime = '=?utf-8?Q?Schuker_hat_sich_vom_=C3=9Cbungsabend_(01.01.2012)_abgem?= =?utf-8?Q?eldet?=';
echo imap_utf8($mime);
这给了我以下(正确)结果:
Schuker hat sichvomÜbungsabend(01.01.2012)abgemeldet
为什么这样做?我应该依靠哪种方法?
我问的原因是我之前曾问过另一个mail subject decoding related question mb_decode_mimeheader
解决方案,而imap_utf8
就是这样。我怎样才能确保为这两个例子解码所有正确的内容:
=?utf-8?Q?Schuker_hat_sich_vom_ = C3 = 9Cbungsabend_(01.01.2012)_abgem?= =?utf-8?Q?eldet?
和
=?UTF-8 2 B 4 UmU6ICMyLUZpbmFsIEFjY2VwdGFuY2UgdGVzdCB3aXRoIG5ldyB0ZXh0IHdpdGggU2xvdg ==?= =?UTF-8 2 B 4 YWsgaW50ZXJwdW5jdGlvbnMgIivEvsWhxI3FpcW + w73DocOtw6khxYgi?=
应该给我预期的结果:
Schuker hat sichvomÜbungsabend(01.01.2012)abgemeldet
和
回复:#2 - 最终验收测试,带有斯洛伐克语中间节点的新文本“+ľščťžýáíé!”
答案 0 :(得分:7)
根据hbit响应,我改进了imapUtf8()
功能,使用charset信息将主题文本转换为UTF-8。结果如下:
function imapUtf8($str){
$convStr = '';
$subLines = preg_split('/[\r\n]+/', $str);
for ($i=0; $i < count($subLines); $i++) {
$convLine = '';
$linePartArr = imap_mime_header_decode($subLines[$i]);
for ($j=0; $j < count($linePartArr); $j++) {
if ($linePartArr[$j]->charset === 'default') {
if ($linePartArr[$j]->text != " ") {
$convLine .= ($linePartArr[$j]->text);
}
} else {
$convLine .= iconv($linePartArr[$j]->charset, 'UTF-8', $linePartArr[$j]->text);
}
}
$convStr .= $convLine;
}
return $convStr;
}
答案 1 :(得分:1)
这也在mb_decode_mimeheader
手册的评论中,我实际上认为这是一个错误。数据库中没有,所以我将其作为新文件提交。
但是,AFAIK imap_mime_header_decode
会毫无问题地处理您的编码,这样可以保持代码的正常运行。
答案 2 :(得分:1)
此功能适用于两个示例:
function imapUtf8($str){
$convStr = '';
$subLines = preg_split('/[\r\n]+/',$str); // split multi-line subjects
for($i=0; $i < count($subLines); $i++){ // go through lines
$convLine = '';
$linePartArr = imap_mime_header_decode(trim($subLines[$i])); // split and decode by charset
for($j=0; $j < count($linePartArr); $j++){
$convLine .= ($linePartArr[$j]->text); // append sub-parts of line together
}
$convStr .= $convLine; // append to whole subject
}
return $convStr; // return converted subject
}
试验:
$sub1 = '=?utf-8?Q?Schuker_hat_sich_vom_=C3=9Cbungsabend_(01.01.2012)_abgem?= =?utf-8?Q?eldet?=';
$sub2 = '=?UTF-8?B?UmU6ICMyLUZpbmFsIEFjY2VwdGFuY2UgdGVzdCB3aXRoIG5ldyB0ZXh0IHdpdGggU2xvdg==?= =?UTF-8?B?YWsgaW50ZXJwdW5jdGlvbnMgIivEvsWhxI3FpcW+w73DocOtw6khxYgi?=';
echo imapUtf8($sub1);
echo imapUtf8($sub2);
结果:
Schuker hat sichvomÜbungsabend(01.01.2012)abgemeldet
回复:#2 - 最终验收测试,带有斯洛伐克语中间节点的新文本“+ľščťžýáíé!”
答案 3 :(得分:0)
关于主题标题字段中的神秘下划线:
RFC2047 4.2(2)明确说明:
8位十六进制值20(例如,ISO-8859-1 SPACE)可以是 表示为&#34; _&#34; (下划线,ASCII 95.)。 (这个角色可能会 不通过一些互联网邮件网关,但它的使用 将大大提高&#34; Q&#34;的可读性。邮件编码数据 不支持此编码的读者。)请注意&#34; _&#34; 始终表示十六进制20,即使是SPACE字符 在使用的字符集中占用不同的代码位置。
主题行的编码规则记录在RFC2047中。