Подтвердить что ты не робот

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

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

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

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

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

4b9b3361

Ответ 1

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

SET NAMES utf8

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

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

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

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

Ответ 2

Сопоставление и кодировка - это не одно и то же. Ваша сортировка должна соответствовать кодировке, поэтому, если ваша кодировка - 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, но может привести к некоторой царапине головки. Отключите его, ради собственного здравого смысла.

Ответ 4

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

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

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

Ответ 5

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

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

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

Ответ 6

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

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