如何自动将电子邮件附件文件名转换为UTF-8(使用Mail_mimeDecode)


How to automatically convert email attachment filename to UTF-8 (using Mail_mimeDecode)

我使用Mail_mimeDecode从传入的电子邮件中提取附件。有一段时间一切都运行良好,直到我开始接收带有KOI8编码的文件名的附件,其部分标题如下:

Content-Disposition: attachment; filename="=?KOI8-R?B?8NLJzM/Wxc7JxSAudHh0?="

mimeDecode做了一件非常合理的事情,并返回KOI8中的文件名:

$attachmentNameInKOI8 = $part->d_parameters['filename'];

问题是,我需要它在UTF-8。在这个特定的示例中,我可以运行以下命令来进行转换:

$attachmentNameInUTF8 = iconv('KOI8', 'UTF-8', $attachmentNameInKOI8);

但是没有尝试手动解析消息,我不知道名称何时在KOI8中,何时不在KOI8中。我还担心其他编码很快就会出现,所以我需要一种方法来处理可能出现的任何情况。

我读到mb_detect_encoding是不可靠的,事实上我不能让它检测字符串为KOI8。

是否有办法告诉mimeDecode为我做翻译?我看了看mimeDecode.php:_decodeHeader()的源代码,我可以看到它解析编码,但随后不做任何事情,这似乎是一个浪费的机会。

更新:要清楚,这只是标头的问题,而不是主体,因为mimeDecode暴露了主体的字符集,所以很容易自己运行iconv,像这样:

$bodyutf = iconv($textpart->ctype_parameters['charset'], 'UTF-8', $textpart->body);

在_decodeHeader()之前添加一行似乎可以解决问题:

$text = iconv($charset, 'UTF-8', $text);
$input = str_replace($encoded, $text, $input);

似乎很奇怪,他们没有在原始类中建立一些这样的选项,不是吗?

:我已经注意到主题行和其他标头也可以像文件名一样编码(RFC2047)。似乎在_decodeHeader中添加iconv行可以解决所有这些情况。

奇怪的是,mimeDecode没有内置这样的功能——这不是一个罕见的问题。

EDIT:我现在明白了,mimeDecode具有decode_headers=false选项的意义是获得原始值,以便您可以自己解码它们。这似乎是一种浪费,因为如果你不能相信mimeDecode会以预期的字符集返回字符串,那么让mimeDecode解码你的头ever就没有意义了(接受字符集作为解码的参数会更有意义;或者null表示不解码…我有一种感觉,他们不太可能为小我改变。)所以关键是你需要自己解码。不幸的是,它不像直接调用imap_utf8()或imap_mime_header_decode()那么简单。您可以从mimeDecode中获取_decodeHeader()函数并对其进行修改,或者使用如下内容:

http://www.php.net/manual/en/function.imap-mime-header-decode.php # 71762

EDIT #2:令人难以置信的是,mimeDecode的家伙已经把我的建议纳入了他们最新的svn:

https://pear.php.net/bugs/bug.php?id=18876

在该版本中,您现在可以设置decode_headers='UTF-8',并且mimeDecode将为您完成所有工作。哇!