Описание проблемы
После обновления PHP на нашем сервере разработки с 5.2 до 5.3 мы сталкиваемся с проблемой, когда данные, запрошенные из нашей базы данных и отображаемые на веб-странице, показывают неправильное кодирование при попытке отображать русские символы.
Окружающая среда
- Dev OS: Debian GNU/Linux 6.0
- Dev PHP: 5.3.5-0.dotdeb.1
- Live MySQL: Распространение 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 и пытаемся отобразить одни и те же данные, она становится искаженной. В этом конкретном случае мы пытаемся отображать русские символы, а результат - неанглийские, нерусские символы:
Полученные заголовки ответов подтверждают, что тип содержимого UTF-8:
Мы тестировали строки перед отображением 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 в нашей системе разработки до версии 5.1.55. После этого обновления все отображается правильно, когда мы подключались к нашей базе данных разработки. Конечно, он продолжает отображаться некорректно, когда мы подключаемся к нашей активной базе данных.
В идеале мы хотели бы решить эту проблему без обновления MySQL на наших производственных серверах, если мы не сможем проверить точную причину, по которой это не работает, и почему обновление исправит его. Как решить эту проблему без обновления MySQL? В качестве альтернативы, почему обновление MySQL исправляет проблему?