Лучшие практики в PHP и MySQL с международными строками - PullRequest
19 голосов
/ 26 сентября 2008

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

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

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

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

Ответы [ 6 ]

14 голосов
/ 26 сентября 2008

При первом взгляде на 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");

при инициализации соединения с БД.

8 голосов
/ 27 сентября 2008

Collation и charset - это не одно и то же. Ваше сопоставление должно соответствовать кодировке, поэтому, если ваш набор символов - utf-8, то же самое должно быть и в сопоставлении. Выбор неправильной сортировки не будет искажать ваши данные - просто сделайте сравнение / сортировку строк некорректно.

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

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

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

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

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

2 голосов
/ 27 сентября 2008

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

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

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

2 голосов
/ 26 сентября 2008

Не так много, чтобы сказать, что не рассматривается в этой статье

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

0 голосов
/ 27 сентября 2008

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

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

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

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

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

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