Поврежденные символы UTF-8 с PHP 5.2.10 и MySQL 5.0.81 - PullRequest
2 голосов
/ 18 января 2010

У нас есть приложение, размещенное как на локальном сервере разработки, так и на работающем сайте. У нас возникают проблемы с коррупцией в UTF-8, и мы ищем способы их решения.

Система работает с использованием Symfony 1.0 с Propel.

На нашем сервере разработки мы используем PHP 5.2.0 и MySQL 5.0.32. Мы не видим там поврежденных символов UTF-8.

На нашем работающем сайте работают PHP 5.2.10 и MySQL 5.0.81. На этом сервере некоторые символы, такие как и Σ , будут повреждены после их сохранения в базе данных. Поврежденные символы отображаются в виде вопросительных знаков или приближений исходного символа с соседними вопросительными знаками.

Примеры коррупции:

Не повреждено: ố Поврежден: ô?

Не повреждено: Σ Поврежден:?

В настоящее время мы используем следующие методы как на серверах разработки, так и на живых серверах:

  1. Выполнение следующих запросов перед выполнением любых других запросов:

    SET NAMES 'utf8' COLLATE 'utf8_unicode_ci'
    SET CHARSET 'utf8'
    
  2. Установка значения <meta> Content-Type на:

    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    
  3. Добавление следующего к нашему файлу .htaccess:

    AddDefaultCharset utf-8
    
  4. Использование mb_* (многобайтовых) функций PHP там, где это необходимо.

  5. Обязательно установите столбцы базы данных для использования сортировки utf8_unicode_ci.

    Этих методов достаточно для нашего сайта разработки, но они не работают на живом сайте.

На живом сайте я также пытался добавить mysql_set_encoding('ut8', $mysql_connection), но это тоже не помогает. Я нашел доказательства того, что более новые версии PHP и MySQL неправильно обрабатывают кодировки символов UTF-8.

Ответы [ 5 ]

3 голосов
/ 18 января 2010

Возьмите минимальный пример - отправьте форму, скажем, символом Σ, и определите, где в пути от браузера к базе данных она повреждена. Напечатайте значение bin2hex ($ str) в журнал в вашем приложении PHP, как можно скорее после получения запроса от браузера, последнее, прежде чем передать его в базу данных, и в любом другом месте, где вы подозреваете, может быть проблемная область - для Σ он должен распечатать cea3 . В базе данных запустите charset (col), hex (col) для сохраненных данных - если все это работает, следует распечатать ["utf8", "cea3"] (при условии, что таблицы имеют utf8).

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

1 голос
/ 19 января 2010

Наш опытный системный администратор обнаружил исправление:

alter database DB_NAME character set utf8;

Это полностью решило наши проблемы.

1 голос
/ 18 января 2010

Обратите внимание, что если вы используете Doctrine или Propel mysql_set_encoding() не будет иметь никакого эффекта, так как оба ORM основаны на PDO (Propel <1.3 основан на Creole / Mysqli). </p>

0 голосов
/ 03 мая 2010

У меня была такая же проблема, но это не MySQL, поскольку Doctrine позаботился обо всем, от сортировки БД до таблиц и соединения в UTF-8.

Я обнаружил, что substr() вызывает проблемы с умляутами (ü), поэтому я переключился на mb_substr(), mb_strlen() и т. Д. Для ввода данных пользователем. Не забудьте про настройку ini, иначе она не будет работать:

ini_set('mbstring.internal_encoding','UTF-8');

OR

mbstring.internal_encoding = UTF-8; //in php.ini
0 голосов
/ 18 января 2010

Символы повреждены только после их сохранения в БД? А как насчет PHP?

Попробуйте добавить атрибут accept-charset="UTF-8" к элементам формы.


Также убедитесь, что ваши .php файлы имеют кодировку UTF-8 без BOM.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...