Лучшие практики в PHP и MySQL с международными строками

Часто бывает, что символы, такие как é, преобразуются в Ã © , хотя для сортировки для БД MySQL таблицы и поля установлено значение utf8_general_ci. Кодировка в Content-Type для страницы также установлена ​​в UTF8.

Я знаю об utf8_encode / decode, но я не совсем уверен, где и как его использовать.

Я прочитал статью « Абсолютный минимум для всех разработчиков программного обеспечения, абсолютно положительно должен знать о Unicode и наборах символов (без отговорок!) », Но мне нужны некоторые указатели на MySQL / PHP.

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

На первом взгляде на http://www.nicknettleton.com/zine/php/php-utf-8-cheatsheet я думаю, что одна важная вещь отсутствует (возможно, я пропустил это). В зависимости от вашей установки и / или конфигурации MySQL вы должны установить кодировку соединения, чтобы MySQL знал, какую кодировку вы ожидаете на стороне клиента (что означает клиентскую часть соединения MySQL, которая должна быть вашим PHP-скриптом). Вы можете сделать это, вручную выпустив

SET NAMES utf8 

запрос перед любым другим запросом, отправляемым на сервер MySQL.

Если вы используете PDO на стороне PHP, вы можете настроить подключение для автоматического запроса этого запроса на каждом (повторном) соединении, используя

 $db=new PDO($dsn, $user, $pass); $db->setAttribute(PDO::MYSQL_ATTR_INIT_COMMAND, "SET NAMES utf8"); 

при инициализации вашего соединения db.

Сортировка и кодировка – это не одно и то же. Ваша сортировка должна соответствовать кодировке, поэтому, если ваша кодировка – utf-8, то и сопоставление. Выбор неправильной сортировки не будет искажать ваши данные, хотя – просто сделайте операцию сравнения строк / сортировки неправильно.

Тем не менее, есть несколько мест, где вы можете установить настройки набора символов в PHP. Я бы рекомендовал вам использовать utf-8 всюду, если это возможно. Места, для которых требуется кодировка, указаны:

  • База данных. Это можно установить на уровне базы данных, таблицы и поля и даже на уровне каждого запроса.
  • Связь между PHP и базой данных.
  • HTTP-выход; Убедитесь, что HTTP-заголовок Content-Type указывает utf-8. Вы можете установить значения по умолчанию в PHP и Apache, или вы можете использовать функцию header PHP.
  • HTTP-вход. Обычно формы будут подаваться в той же кодировке, что и страница, но, чтобы убедиться, вы должны указать свойство accept-charset . Также убедитесь, что URL-адрес закодирован в utf-8 или не использует символы не-ascii в параметрах url (и GET).

utf8_encode / utf8_encode немного странно названы. Они специально конвертируют между latin1 (ISO-8859-1) и utf-8. Если все в вашем приложении – utf-8, вам не придется много использовать их.

Есть как минимум две ошибки в отношении utf-8 и PHP. Во-первых, встроенные строковые функции PHP ожидают, что строки будут однобайтными. Для многих операций это не имеет значения, но это означает, что вы не можете полагаться на strlen и другие функции. На этой странице есть хорошие ограничения на ограничения. Как правило, это не большая проблема, но особенно при использовании 3-сторонних библиотек вы должны знать, что на это могут взорваться. Один из вариантов – также использовать расширение mb_string, которое может заменить все проблемные функции с помощью вариантов, поддерживающих utf-8. Это все еще не 100% пуленепробиваемое решение, но оно будет работать в большинстве случаев.

Другая проблема заключается в том, что в некоторых установках PHP по-прежнему включен параметр magic_quotes . Эта проблема ортогональна utf-8, но может привести к некоторой царапине головки. Выключите это, ради собственного здравого смысла.

Нельзя сказать, что эта статья не рассматривается

http://developer.loftdigital.com/blog/php-utf-8-cheatsheet

Что вы должны сделать:

  • Убедитесь, что Apache выпускает содержимое UTF-8. Сделайте это в своем httpd.conf или используйте функцию header() для PHP, чтобы сделать это вручную.
  • Убедитесь, что соединение с базой данных UTF8. SET NAMES utf8 делает трюк.
  • Убедитесь, что для всех ваших таблиц установлено значение UTF8.
  • Убедитесь, что все ваши файлы PHP и шаблонов закодированы как UTF8, если вы храните в них международные символы.

Обычно вы не должны многого использовать с помощью mb_string или utf8_encode/decode когда вы это делаете.

Для правильной правильности юникода вы должны использовать utf8_unicode_ci (хотя документация немного расплывчата в различиях). Вы также должны убедиться, что следующие флаги Mysql установлены правильно –

  • по умолчанию-символьный набор = utf8
  • skip-character-set-client-handshake // Важно, чтобы клиент не применял другую кодировку

Они могут быть установлены в файле конфигурации mysql (на вкладке [mysqld]) или во время выполнения, отправив соответствующие запросы.

Независимо от языка, на котором он написан, если вы должны создать приложение, которое позволяет широкий спектр кодировок, обрабатывать его по частям:

  • Определить кодировку
    • каким-то образом вы хотите узнать, с какими кодировками вы имеете дело, в противном случае довольно бессмысленно рассматривать его дальше. В итоге у вас появятся хлам.
  • Обрабатывайте свои байты
    • думайте об этих строках меньше, как «строки» символов, и больше похожи на списки байтов
    • PHP особенно подлый. Не позволяйте ему урезать ваши данные «на лету». Если вы повторяете строку UTF-8, убедитесь, что вы ее идентифицируете как таковую
  • Магазин для ЖК-дисплея
    • Опять же, вы не хотите усекать данные. Если вы храните предложение на английском языке, можете ли вы также сохранить набор мандаринских символов? Как насчет арабского? Какие из них потребуют больше всего пространства? Учтите это.