Устранение неправильной кодировки символов при отображении результатов базы данных MySQL после обновления до PHP 5.3 - PullRequest
10 голосов
/ 04 марта 2011

Описание проблемы

После обновления PHP на нашем сервере разработки с 5.2 до 5.3 мы столкнулись с проблемой, когда данные, запрашиваемые из нашей базы данных и отображаемые на веб-странице, отображаются с неправильной кодировкой при попытке отобразить русский язык.символов.

Среда

  • Dev OS: Debian GNU / Linux 6.0
  • Dev PHP: 5.3.5-0.dotdeb.1
  • Live MySQL: Distrib 5.1.49

Подробности

В PHP 5.3 стандартная клиентская библиотека для взаимодействия с базами данных MySQL была изменена с libmysql на mysqlnd , чтопохоже, причина проблемы, с которой мы сталкиваемся.

Мы подключаемся к базе данных с помощью следующего кода:

$conn = mysql_pconnect('database.hostname', 'database_user', 'database_password');
$mysql_select_db('database', $conn);

Данные, хранящиеся в нашей базе данных, кодируются с помощью UTF-8.кодирование.Подключение к базе данных через клиент командной строки и выполнение запросов подтверждает, что данные не повреждены и правильно закодированы.Однако, когда мы запрашиваем базу данных на PHP и пытаемся отобразить те же самые данные, она искажается.В данном конкретном случае мы пытаемся отобразить русские символы, и в результате получаются не английские, не русские символы: garbled mess

Получаемые нами заголовки ответа подтверждают, что тип содержимого - UTF-8.:

response headers

Мы протестировали строки перед отображением с mb_detect_encoding в строгом режиме, а также mb_check_encoding и получили сообщение, что строка былаСтрока UTF-8 перед отображением.Мы также использовали mysql_client_encoding для проверки клиентской кодировки, и это также указывает, что набор символов - UTF-8.

В ходе исследования мы обнаружили некоторые предложения , чтобы попытатьсяОбойти эту проблему:

header("Content-type: text/html; charset=utf-8");
mysql_set_charset('utf8');
mysql_query("SET SESSION character_set_results = 'UTF8'");
mysql_query('SET NAMES UTF8', $conn);

Мы даже попробовали utf8_encode :

utf8_encode($string);

Однако ни одно из этих решений не сработало.

Выполняетсяопций мы обновили MySQL в нашей системе разработки до Distrib 5.1.55.После этого обновления все отображалось правильно, когда мы подключались к нашей базе данных разработки.Конечно, он продолжает отображаться неправильно, когда мы подключаемся к нашей действующей базе данных.

В идеале, мы хотели бы решить эту проблему, не обновляя MySQL на наших производственных серверах, если мы не сможем установить точную причину, почему это не так.работает и почему обновление это исправит. Как мы можем решить эту проблему кодирования без обновления MySQL?В качестве альтернативы, почему обновление MySQL устраняет проблему?

Ответы [ 3 ]

3 голосов
/ 04 марта 2011

Если вы убедились, что и таблицы, и выходная кодировка имеют формат UTF-8, почти единственное, что осталось, - это кодировка соединения.

Причиной изменения поведения при обновлении серверов может быть изменение кодировки соединения по умолчанию:

[mysql]
default-character-set=utf8

Однако я не вижу никаких изменений в кодировке по умолчанию между версиями, поэтому, если это были совершенно новые установки, я не вижу, что это происходит.

В любом случае, что произойдет, если вы запустите это из своего PHP-запроса и выдадите результаты. Есть ли различия в выводе командной строки?

 SHOW VARIABLES LIKE 'character_set%';
 SHOW VARIABLES LIKE 'collation%'; 
3 голосов
/ 04 марта 2011

Я вижу, что вы пробовали это, но синтаксис, который я использую: mysql_query ("SET NAMES utf8").Ваш синтаксис может быть правильным, я просто никогда не видел его таким.

Пример:

// connect to database stuff
$Connection = mysql_connect($server, $username, $password)
or die ("Error connecting to server");

// connect to database stuff
$db = mysql_select_db($database, $Connection)
or die ("Error selecting database");

mysql_query("SET NAMES utf8");
0 голосов
/ 09 марта 2011

У меня была похожая проблема после обновления PHP с 5.2.3 до 5.3.5 (5.3.5-Win32-VC6-x86), MySQL 5.0.41 (не обновлено).Я думаю, что причина в небольшой разнице между версиями PHP.

PHP 5.2.3 по умолчанию (без SET NAMES): character_set_client = latin1character_set_connection = latin1character_set_database = utf8character_set_filesystem = двоичныйcharacter_set_results = latin1character_set_server = latin2character_set_system = utf8collation_connection = latin1_swedish_cicollation_database = utf8_polish_cicollation_server = latin2_general_ci

PHP 5.3.5 по умолчанию (без SET NAMES): character_set_client = latin2character_set_connection = latin2character_set_database = utf8character_set_filesystem = двоичныйcharacter_set_results = latin2character_set_server = latin2character_set_system = utf8collation_connection = latin2_general_cicollation_database = utf8_polish_cicollation_server = latin2_general_ci

Я добавил данные в базу данных по умолчанию в PHP 5.2.3 (без SET NAMES), поэтому теперь, чтобы отобразить их правильно, я должен прочитать их, используя:

$pdo -> query("SET NAMES 'latin1'");

Может быть, что-то подобноеявляется причиной вашей проблемы.

...