2

我正在阅读粘贴到电子邮件正文中的日志文件,其中一些使用各种不同的语言,并且所有语言字符似乎都能正确显示,但俄语除外。

以下是俄罗斯人在日志文件中所说的示例:

Ссылка на объект не указывает на экземпляр объекта。

从我读过的内容来看,我需要在 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取出正文,它就会从俄语转换为该编码,我可以剖析类似代码的任何指针以了解如何解决这个问题?

请记住,从电子邮件中读取了多种语言,大部分只是一些片段,其余的是基本日志记录,但我担心的是,如果我设置了一个新的解码,它会弄乱其他语言字符

4

1 回答 1

2

尽管电子邮件被广泛采用,但使用起来仍然很棘手。如果您的 IMAP 客户端的要求有限,那么您的工作将很容易。否则,对于真正的通用 GMail 客户端,没有灵丹妙药,您必须不了解电子邮件是如何工作的:SMTP、MIME,最后是 IMAP。

基本的 MIME 知识是绝对需要的,我不会粘贴整个 wikipedia 文章,但您应该真正阅读并了解它是如何工作的。IMAP 更容易理解。

通常,电子邮件包含单个text/plain正文,或包含text/plaintext/html部分的多部分/替代正文。但是,你知道,有附件,所以你也可以找到一个multipart/mixed并且它真的可以包含任何东西,如果它是二进制内容,你应该区别对待它而不是文本。有两个标题(您可以在全局消息中或部分在多部分信封中找到)在某种程度上涉及字符集问题:Content-TypeContent-Transfer-Encoding

从您的代码中,我们必须假设您只对base64 编码的文本部分感兴趣。一旦你解码了它们,它们就是一个字节序列,表示发送者在Content-Type标头中指定的字符集中的文本,这里是非 ASCII,因此看起来像这样:

Content-Type: text/plain; charset=ISO-8859-1

请注意,字符集可能是utf8或您能想到的任何其他字符集,您必须在程序中检查这一点。您的工作是在 HTML 页面的输出字符集中对这段输入进行转码。如果您的页面不使用 Unicode 编码(如 UTF-8),您可能甚至无法正确显示消息,并且“?” 将被打印而不是缺少字符。由于您要求您的应用程序在全球范围内使用(不仅仅是在俄罗斯),而且无论如何这是一种很好的做法,您应该在 HTML 响应中使用 UTF-8,因此当您想要回显消息正文时:

echo mb_convert_encoding(imap_base64($body), "UTF-8", $input_charset);

在已处理部分的Content-Type$input_charset标头中找到的那个在哪里。对于主题行,您应该使用,它返回一个元组数组(二进制字符串、字符集),您必须以与上述相同的方式输出该数组。imap_mime_header_decode()

TL;博士

如果我们假设它是CP-1252编码的(也许你没有复制一些不可打印的),那么 UTF-8 编码的输入文本中的字节可以很好地映射到输出。这意味着输入是 UTF-8,但浏览器认为页面是 Windows-1252。可能这是您的语言环境的默认浏览器行为,您可以通过在任何其他输入之前发送适当的标头来轻松纠正它:

header("Content-Type: text/html; charset=utf-8");

这应该足以解决问题,但也可能导致字符串文字和数据库(如果有)中的非 ASCII 字符出现问题。如果您想要一个多语言应用程序,Unicode 是一种方式,但您必须将您的数据库和 PHP 文件从 CP-1252 转码为 UTF-8。

于 2012-12-31T11:04:50.973 回答