Русский язык кодируется при использовании imap-выборки из gmail


Я читаю файл журнала, вставленный в текст электронного письма, некоторые из них написаны на разных языках, и все языковые символы, похоже, отображаются правильно, за исключением русского.

Вот пример того, что русский говорит в файле журнала:

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

В

Из того, что я прочитал, мне нужно указать декодирование или кодирование чего-либо в строках mb_encoding (UTF-8), но я немного запутался в том, как фактически структурируйте его, не затрагивая код, который не является русским. Но когда его повторяют, он преобразуется в следующее:

Ð ¡ÑÑ"Ð"кананбъÐΜкÑ'нÐΜ ÑƑказС"Ð2аÐΜÑ'наÐкÐ*ÐΜÐ ¼ð¿Ð"ÑÑ€ нбъÐΜкÑ'а. Ð2

Вот код, который я уже использую, я новичок в php, и кое-что из этого не мой код, я отредактировал в соответствии, но не на 100%, что все делает:

$mailbox = "[email protected]";
$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 выведу тело, оно преобразуется с русского языка в эту кодировку, любые указатели на похожий код я могу разобрать, чтобы узнать, как это исправить?

Пожалуйста, имейте в виду, что из письма было прочитано множество языков, по большей части это всего лишь несколько фрагментов, а остальное - простое ведение журнала, но меня беспокоит то, что если я установлю новый декод, это испортит другие языковые символы

Author: Raffaele, 2012-12-31

1 answers

Несмотря на широкое распространение электронной почты, с ней по-прежнему сложно работать. Если ваш IMAP-клиент имеет ограниченный набор требований, ваша работа будет легкой. В противном случае, для действительно универсального клиента Gmail нет серебряной пули, и вам нужно понять, как работает электронная почта: SMTP, MIME и, наконец, IMAP.

Базовые знания MIME абсолютно необходимы, и я не буду вставлять всю статью википедии, но вы действительно должны прочитать ее и понять, как она работает. IMAP несколько легче понять.

Обычно сообщения электронной почты содержат либо одно текстовое/простое тело, либо составное/альтернативное тело, содержащее как текст/простое, так и текст/html часть. Но, вы знаете, есть вложения, так что вы также, вероятно, можете найти составной/смешанный, и он действительно может содержать что угодно, и если это двоичный контент, вы должны относиться к нему иначе, чем к тексту. Есть два заголовка (которые вы можете найти в глобальном сообщение или частично внутри составного конверта), несколько связанного с проблемами кодировки: Тип содержимого и Кодирование передачи содержимого.

Из вашего кода мы должны предположить, что вас интересуют только текстовые части в кодировке base64. После того, как вы их декодировали, они представляют собой последовательность байтов, представляющих текст в кодировке, указанной отправителем в заголовке типа содержимого, который здесь не является ASCII и поэтому выглядит следующим образом:

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

Примечание эта кодировка может быть utf8 или действительно любой другой, о котором вы можете подумать, вы должны проверить это в своей программе. Ваша задача - перекодировать этот фрагмент ввода в кодировку вывода вашей HTML-страницы. Если на вашей странице не используется кодировка Юникода (например, UTF-8), скорее всего, вы даже не сможете правильно отобразить сообщение, и вместо пропущенных символов будет напечатано "?". Поскольку вам требуется, чтобы ваше приложение использовалось во всем мире (не только в России), и поскольку оно в любом случае хорошая практика, вы должны использовать UTF-8 в своих HTML-ответах, и, следовательно, когда вы хотите повторить текст сообщения:

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

Где $input_charset - это заголовок типа содержимого для обрабатываемой части. В строке темы вы должны использовать imap_mime_header_decode(), который возвращает массив кортежей (двоичная строка, кодировка), которые вы должны вывести тем же способом, что и выше.

TL; ДР

Байты входного текста в кодировке UTF-8 довольно хорошо соответствуют вывод, если мы предположим, что это кодировка CP-1252 (возможно, вы не скопировали некоторые непечатаемые файлы). Это означает, что ввод - UTF-8, но браузер считает, что страница Windows-1252. Вероятно, это поведение браузера по умолчанию для вашей локали, и вы можете легко исправить его, отправив соответствующий заголовок перед любым другим вводом:

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

Этого должно быть достаточно для решения этой проблемы , но также, вероятно, вызовет проблемы с символами, отличными от ASCII, в строковых литералах и база данных (если таковая имеется). Если вам нужно многоязычное приложение, вам подойдет Юникод, но вам придется перекодировать вашу базу данных и ваши PHP-файлы с CP-1252 на UTF-8.

 2
Author: Raffaele, 2013-01-01 23:56:18