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

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

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

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

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

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
19
0
12 016
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

Ответ принят как подходящий

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

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

Об этом где-то упоминается в комментариях, но да, это сложно пропустить!

Jrgns 26.09.2008 22:13

Для всех, кто только что читал это (по состоянию на март 2010 г.), ссылка на статью теперь доступна по адресу developer.loftdigital.com/blog/php-utf-8-cheatsheet.

bdl 26.03.2010 21:55

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

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

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

Что вам следует делать:

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

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

Сопоставление и кодировка - это не одно и то же. Ваша сортировка должна соответствовать кодировке, поэтому, если ваша кодировка - 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 / decode имеют несколько странное название. Они специально конвертируют между latin1 (ISO-8859-1) и utf-8. Если все в вашем приложении - это utf-8, вам не придется их часто использовать.

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

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

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

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

Другие вопросы по теме