Php 使用imap_从gmail获取时编码的俄语

Php 使用imap_从gmail获取时编码的俄语,php,encoding,imap,Php,Encoding,Imap,我正在阅读粘贴在电子邮件正文中的日志文件,其中一些文件使用不同的语言,除俄语外,所有语言字符都显示正确 以下是俄罗斯人在日志文件中所说的一个示例: Саааааааа 从我所读到的内容来看,我需要在mb_编码(UTF-8)的行中指定解码或编码,但我对如何实际构造它而不影响非俄语的代码有点茫然。但当回音时,它会转换为: 2008年8月18日,在2008年8月18日的现场现场现场现场现场的现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现

我正在阅读粘贴在电子邮件正文中的日志文件,其中一些文件使用不同的语言,除俄语外,所有语言字符都显示正确

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

Саааааааа

从我所读到的内容来看,我需要在mb_编码(UTF-8)的行中指定解码或编码,但我对如何实际构造它而不影响非俄语的代码有点茫然。但当回音时,它会转换为:

2008年8月18日,在2008年8月18日的现场现场现场现场现场的现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场цÐÐ。 в

以下是我已经在使用的代码,我是一名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
out body它将俄语转换成那种编码,我可以剖析类似代码上的任何指针来学习如何解决这个问题吗


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

尽管电子邮件被大量采用,但它仍然很难处理。如果您的IMAP客户端有一组有限的需求,那么您的工作将很容易。否则,对于一个真正的通用GMail客户端来说,没有银弹,你必须理解电子邮件是如何工作的:SMTP、MIME,最后是IMAP

基本的MIME知识是绝对必要的,我不会粘贴整个维基百科文章,但你应该真正了解它是如何工作的。IMAP比较容易理解

通常,电子邮件包含单个文本/纯文本正文,或包含文本/纯文本和文本/html部分的多部分/可选正文。但是,你知道,有附件,所以你也可以找到一个多部分/混合的,它可以真正包含任何内容,如果它是二进制内容,你应该区别于文本。在字符集问题中有两个标题(可以在全局消息中找到,也可以在多部分信封中找到):内容类型和内容传输编码

从您的代码中,我们必须假设您只对base64编码的文本部分感兴趣。解码后,它们是一个字节序列,表示发送方在内容类型标头中指定的字符集中的文本,此处为非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);
其中,
$input\u字符集
是在已处理零件的内容类型标题中找到的字符集。对于主题行,您应该使用,它返回元组数组(二进制字符串,字符集),您必须以与上面相同的方式输出该数组

TL;DR

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

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

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

感谢您的详细回答,我尝试通过以下方式访问电子邮件字符集:$headers1=imap_fetchstructure($mailbox,$val);但即使是俄罗斯的电子邮件都显示为UTF-8,所以我不知道如何找出我必须进行mb_转换_编码的邮件on@user1547410我听不懂你说的话,请重新措辞。另外,如果发送方程序在您的控制下,您可以检查它的一侧,以了解消息的编码基本上我正在尝试为$input_字符集找到正确的值。我想我可能会在imap_结构中找到它,但一切都返回UTF-8。我无法控制发送原件的程序email@user1547410你能粘贴整个页眉吗?如果字符串是二进制utf8,并且您的输出页面也是utf8,那么将没有problem@user1547410我做了一些测试。错误在于HTML,因为它使用了一些8位字符编码(可能是windows代码页或一些ISO-8859变体)。这不适用于多语言应用程序,因为Unicode字符不能用有限的字符集表示。您必须切换整个前端编码