我正在阅读粘贴在电子邮件正文中的日志文件,其中一些是各种不同的语言,除了俄语之外,所有语言字符似乎都正确显示。
以下是俄语在日志文件中说明的一个示例:
Ссылканаобъектнеуказываетнаэкземпляробъекта。
в
根据我的阅读,我需要在mb_encoding(UTF-8)的行中指定解码或编码,但我对如何实际构造它而不影响不是俄语的代码有点迷失。但是当它被回复时,它会被转换为:
СÑÑ<лÐÐÐÐÐÐÐÐÐÐÐ~~~~~~~~~~ в
这是我已经使用的代码,我是一个php初学者,其中一些不是我的代码,我已编辑以适应但不是100%一切都在做:
$mailbox = "xxx@gmail.com";
$mailboxPassword = "xxx";
$mailbox = imap_open("{imap.gmail.com:993/imap/ssl}INBOX",
$mailbox, $mailboxPassword);
mb_internal_encoding("UTF-8");
$subject = mb_decode_mimeheader(str_replace('_', ' ', $subject));
$body = imap_fetchbody($mailbox, $val, 1);
$body = base64_decode($body);
echo $body;
一旦我echo
身体,它从俄语转换为该编码,我可以剖析类似代码的任何指针,以了解如何解决这个问题?
请记住,从电子邮件中读取了大量语言,其中大部分只是几个片段,其余的是基本日志,但我担心的是,如果我设置一个新的解码,它会搞砸其他语言字符
答案 0 :(得分:2)
尽管电子邮件采用率很高,但仍然难以使用电子邮件。如果您的IMAP客户端有一组有限的要求,您的工作将很容易。否则,对于一个真正的通用GMail客户端,没有灵丹妙药,你必须不明白电子邮件wokrs:SMTP,MIME和最终IMAP。
绝对需要基本的MIME知识,我不会粘贴整个维基百科文章,但您应该read it并了解其工作原理。 IMAP更容易理解。
通常,电子邮件消息包含单个 text / plain 正文,或者包含 text / plain 的 multipart / alternative 正文一个 text / html 部分。但是,你知道,有附件,所以你也可能找到一个 multipart / mixed ,它实际上可以包含任何东西,如果它是二进制内容,你应该区别于文本。在charset问题中有两个标题(您可以在全局消息中找到,或者部分在多部分包络内找到): Content-Type 和 Content-传输编码。
从您的代码中,我们必须假设您只对文本部分 base64编码感兴趣。解码后,它们是一个字节序列,表示发件人在 Content-Type 标题中指定的字符集中的文本,这里是非ASCII,因此看起来像这样:
Content-Type: text/plain; charset=ISO-8859-1
请注意 charset 可能是 utf8 或者您能想到的任何其他内容,您必须在程序中查看此内容。您的工作是在HTML页面的输出字符集中对此输入进行转码。如果您的页面不使用Unicode编码(如UTF-8),则可能无法正确显示消息,并且'?'将打印而不是丢失字符。由于您需要在全球范围内(不仅仅是在俄罗斯)使用您的应用程序,并且因为它无论如何都是良好的做法,您应该在HTML响应中使用UTF-8,因此当您想要回显邮件正文时:
echo mb_convert_encoding(imap_base64($body), "UTF-8", $input_charset);
其中$input_charset
是在已处理部分的 Content-Type 标头中找到的header("Content-Type: text/html; charset=utf-8");
。对于主题行,您应该使用imap_mime_header_decode()
,它返回一个元组数组(二进制字符串,字符集),您必须以与上面相同的方式输出它们。
<强> TL; DR 强>
如果我们假设它是CP-1252编码的(也许你没有复制一些不可打印的),那么UTF-8编码输入文本中的字节与输出相当不错。这意味着输入是UTF-8,但浏览器认为该页面是Windows-1252。可能这是您的语言环境的默认浏览器行为,您可以通过在任何其他输入之前发送适当的标头来轻松纠正它:
{{1}}
这应足以解决此问题,但也可能导致字符串文字和数据库(如果有)中的非ASCII字符出现问题。如果你想要一个多语言应用程序,那就是Unicode,但你必须将数据库和PHP文件从CP-1252转码为UTF-8。