Php 转换内联指定的UTF-8邮件主题

Php 转换内联指定的UTF-8邮件主题,php,email,encoding,utf-8,Php,Email,Encoding,Utf 8,要将以下原始邮件主题转换为普通UTF-8文本: utf-8-Q-Schuker\u hat\u sich\u vom\uC3=9Cbungsabend(2012年1月1日)\u abgem?=“utf-8-Q-eldet?”= 真正的文本是: 舒克帽子(2012年1月1日)abgemeldet 我的第一个转换方法是: $mime = '=?utf-8?Q?Schuker_hat_sich_vom_=C3=9Cbungsabend_(01.01.2012)_abgem?= =?utf-8?Q?e

要将以下原始邮件主题转换为普通UTF-8文本:

utf-8-Q-Schuker\u hat\u sich\u vom\uC3=9Cbungsabend(2012年1月1日)\u abgem?=“utf-8-Q-eldet?”=

真正的文本是:

舒克帽子(2012年1月1日)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);
$mime = '=?utf-8?Q?Schuker_hat_sich_vom_=C3=9Cbungsabend_(01.01.2012)_abgem?=  =?utf-8?Q?eldet?=';
echo imap_utf8($mime);
这给了我以下结果:

舒克(2012年1月1日)

(这里的问题:我做错了什么?为什么会出现这些下划线?)

我的第二种转换方法是:

$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);
$mime = '=?utf-8?Q?Schuker_hat_sich_vom_=C3=9Cbungsabend_(01.01.2012)_abgem?=  =?utf-8?Q?eldet?=';
echo imap_utf8($mime);
这给了我以下(正确)结果:

舒克帽子(2012年1月1日)abgemeldet

为什么这样做有效?我应该依靠哪种方法

我问这个问题的原因是,我之前问过另一个问题,解决方案是
mb\u decode\u mimeeheader
在哪里,而在这里
imap\u utf8
才是解决方法。如何确保对这两个示例的所有内容进行正确解码:

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
} 
utf-8-Q-Schuker\u hat\u sich\u vom\uC3=9Cbungsabend(2012年1月1日)\u abgem?=“utf-8-Q-eldet?”

=?UTF-8?B?UmU6ICMyLUZpbmFsIEFjY2VwdGFuY2UgdGVzdCB3aXRoIG5ldyB0ZXh0IHdpdGggU2xvdg=== =?UTF-8?B?YWSGAW50ZXJWDW5JDGLVBNMGIIVESWHXI3FPCW+w73DocOtw6khxYgi=

应该给我预期的结果:

舒克帽子(2012年1月1日)abgemeldet

回复:#2-最终验收测试,新文本带有斯洛伐克语的交互功能“+ľťťťýýýý!ň”


它也在手册的注释中,我实际上认为这是一个bug。数据库中没有,所以我将它作为新文件归档


但是,AFAIK将毫无问题地处理这两种编码,从而使代码继续运行。

此函数适用于两个示例:

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
} 
结果:

舒克帽子(2012年1月1日)abgemeldet

回复:#2-最终验收测试,新文本带有斯洛伐克语的交互功能“+ľťťťýýýý!ň”


关于主题标题字段中的神秘下划线:

4.2(2)明确规定:

8位十六进制值20(例如,ISO-8859-1空格)可以是 表示为“u”(下划线,ASCII 95.)。(此字符可能 不是通过一些互联网邮件网关,而是它的使用 将大大提高邮件中“Q”编码数据的可读性 不支持此编码的读取器。)请注意 始终表示十六进制20,即使空格字符 在正在使用的字符集中占据不同的代码位置

主题行的编码规则记录在RFC2047中。

基于响应,我改进了
imapUtf8()
函数,使用字符集信息将主题文本转换为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;
}
函数imapUtf8($str){
$convStr='';
$subLines=preg_split('/[\r\n]+/',$str);
对于($i=0;$icharset=='default'){
如果($linePartArr[$j]->text!=“”){
$convLine.=($linePartArr[$j]->text);
}
}否则{
$convLine.=iconv($linePartArr[$j]->字符集,'UTF-8',$linePartArr[$j]->文本);
}
}
$convStr.=$convLine;
}
返回$convStr;
}

您确定实文本包含空格吗?它看起来像是用下划线编码的,或者编码它的应用程序有缺陷。不需要对空格进行编码,即使它被编码,也应该是
=20
而不是下划线。是的,真正的文本包含空格。请看修订后的问题。谢谢这就是RFC 2048修改报价可打印文件以用于7位标题的方式。=?encoding?x?…=包装器也在该规范中定义。-如果
imap_utf8
给出了正确的结果,我会毫不犹豫地使用它(但是,我会毫不犹豫地首先使用PHP,所以我可能不是一个合法的源:-)如果坚持
,mb_decode_mimeheaders
是否能正确工作在测试字符串前面?否,添加主题没有帮助。仅使用
imap_utf8
没有帮助,因为它无法转换第二个主题行
Re:#2…
我猜想
imap_utf8()
是在开始添加BOM(字节顺序标记),因此字符串不相等(不可见字符)感谢您为我指出了正确的方向-
imap\u mime\u header\u decode
最终解决了这个问题(请参见我的答案)。在添加每个子部分之前,您还应该检查$linePartArr[$j]->字符集(必要时将字符串转换为UTF-8)。
preg\u split()
应该使用/u修饰符