MySQL выводит западную кодировку в файл UTF-8 PHP

У меня есть следующая проблема: в очень простом запросе phpmysqli:

if ( $result = $mysqli->query( $sqlquery ) ) { $res = $result->fetch_all(); $result->close(); } 

Я получаю строки, ошибочно закодированные как западные кодированные строки, хотя база данных, таблица и столбец находятся в utf8_general_ci . Сам скрипт php является кодировкой utf-8, а части mysql-less скрипта получают правильные кодировки . Так что echo "ő" работает отлично, но echo $res[0] из предыдущего примера выводит символ EF BF BD когда файл просматривается в правильной кодировке UTF-8. Если я вручную переключу кодировку браузера на запад, строки, полученные из mysqli, получат хорошее декодирование, за исключением замены незападающих символов на «?».

Что еще более странно, так это то, что в моей среде разработки это не происходит, а на моем веб-сервере это так. Среда разработчика представляет собой стек LAMP (Uniform Server), в то время как веб-сервер использует nginx.

В этом случае я ввел данные в базу данных, используя phpMyAdmin , и внутри phpmyadmin он отобразился отлично. Сопоставление phpMyAdmin также является utf-8. Я считаю, что проблема должна быть где-то здесь, как на том же веб-сервере, для другого сайта, где я ввожу данные через php (используя POST), та же проблема не возникает . В этом случае данные отображаются корректно как во время ввода, так и во время просмотра (я имею в виду на php-сгенерированных веб-страницах), но специальные символы неверны в phpMyAdmin.

Можете ли вы помочь мне начать отладку? Связано ли это с php или mysql или nginx или phpMyAdmin ?

Related of "MySQL выводит западную кодировку в файл UTF-8 PHP"

Используйте mysqli_set_charset для изменения клиентской кодировки в UTF-8 сразу после подключения:

 $mysqli->set_charset("utf8"); 

Клиентское кодирование – это то, на что MySql ожидает, что ваш вход будет включен (например, когда вы вставляете текст, предоставленный пользователем в поисковый запрос) и что он дает вам результаты (так что он должен соответствовать вашей выходной кодировке, чтобы echo отображалось правильно).

Вам нужно, чтобы он соответствовал кодировке вашей веб-страницы, чтобы учитывать два вышеперечисленных сценария и кодировку исходного файла PHP (так, чтобы жестко закодированные части ваших запросов были правильно интерпретированы).

Обновление: как конвертировать данные, вставленные с использованием latin-1 в utf-8

Что касается данных, которые уже были вставлены с использованием неправильной кодировки, существует удобное решение для устранения проблемы. Для каждого столбца, который содержит данные такого типа, вам нужно сделать:

 ALTER TABLE table_name MODIFY column_name existing_column_type CHARACTER SET latin1; ALTER TABLE table_name MODIFY column_name BLOB; ALTER TABLE table_name MODIFY column_name existing_column_type CHARACTER SET utf8; 

Заместители table_name , column_name и existing_column_type должны быть заменены правильными значениями из вашей базы данных каждый раз.

Что это делает

  1. Скажите MySql, что он должен хранить данные в этом столбце в latin1. Этот набор символов содержит только небольшое подмножество utf8, поэтому в общем случае это преобразование включает потерю данных, но в этом конкретном сценарии данные уже были интерпретированы как latin1 на входе, поэтому побочных эффектов не будет. Однако MySql будет внутренне преобразовывать представление байтов ваших данных в соответствие с тем, что было первоначально отправлено с PHP.
  2. Преобразуйте столбец в двоичный тип ( BLOB ), который не имеет связанной информации кодирования. В этот момент столбец будет содержать необработанные байты, которые являются правильной символьной строкой utf8.
  3. Преобразуйте столбец в его предыдущий тип символа, сообщая MySql, что необработанные байты следует считать кодировкой utf8.

ПРЕДУПРЕЖДЕНИЕ. Вы можете использовать этот неизбирательный подход только в том случае, если рассматриваемый столбец содержит только неверно вставленные данные. Любые данные, которые были правильно вставлены, будут усечены при первом вводе любого символа, отличного от ASCII!

Поэтому это хорошая идея сделать это прямо сейчас, прежде чем исправление на стороне PHP вступит в силу.

Используйте функцию mysqli :: set_charset.

 $mysqli->set_charset('utf8'); //returns false if the encoding was not valid... won't happen 

http://php.net/manual/en/mysqli.set-charset.php

Я не использовал mysqli в течение некоторого времени, но если все то же самое, соединения по умолчанию используют латинскую шведскую кодировку (ISO 8859 1).

Я рассмотрю, что ваша страница уже использует кодировку utf8, имея:

 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> 

Внутри <head> .

Если у вас уже есть строка с латинской швейцарской кодировкой, вы можете использовать mk_convert_encoding:

http://php.net/manual/en/function.mb-convert-encoding.php

 $fixedStr = mb_convert_encoding($wrongStr, 'UTF-8', 'ISO-8859-1'); 

iconv делает что-то очень похожее: По правде говоря, я не знаю разницы, но вот ссылка на ссылку функции: http://php.net/manual/en/function.iconv.php

Я просто понял, что у вас могут быть некоторые строки в utf8, а другие – латинские. Вы можете использовать mb_detect_encoding для этого: http://php.net/manual/en/function.mb-detect-encoding.php

Вы также можете сбросить базу данных и использовать iconv (cmd line), если она установлена:

 iconv -f latain -t utf-8 < currentdb.sql > fixeddb.sql