Проблемы с символами UTF-8; я не вижу того, что я хранил

Я попытался использовать UTF-8 и столкнулся с проблемой.

Я пробовал так много вещей; вот результаты, которые я получил:

  • ???? вместо азиатских символов. Даже для европейского текста я получил Se?or для Señor.
  • Странная тарабарщина (Mojibake?), такая как Señor или 新浪新闻 для 新浪新闻.
  • Черные бриллианты, такие как Se or.
  • Наконец, я попал в ситуацию, когда данные были потеряны или, по крайней мере, усечены: Se для Señor.
  • Даже когда я получил текст, чтобы выглядеть правильно, он не отсортировался правильно.

Что я делаю неправильно? Как я могу исправить код? Могу ли я восстановить данные, если да, то как?

Ответ 1

Эта проблема преследует участников этого сайта и многих других.

Вы перечислили пять основных случаев проблем CHARACTER SET.

Лучшая практика

В дальнейшем лучше всего использовать CHARACTER SET utf8mb4 и COLLATION utf8mb4_unicode_520_ci. (В конвейере имеется более новая версия сортировки Unicode.)

utf8mb4 является надмножеством utf8 в том смысле, что он обрабатывает 4-байтовые коды utf8, которые нужны Emoji и некоторым китайцам.

За пределами MySQL "UTF-8" относится ко всем кодировкам размеров, следовательно, фактически совпадает с MySQL utf8mb4, а не utf8.

Я попытаюсь использовать эти варианты написания и заглавные буквы, чтобы различать внутренний и внешний MySQL в следующем.

Обзор того, что вы должны делать

  • Настройте редактор и т.д. На UTF-8.
  • HTML-формы должны начинаться как <form accept-charset="UTF-8">.
  • Ваши байты должны быть закодированы как UTF-8.
  • Установите UTF-8 в качестве кодировки, используемой в клиенте.
  • Объявите столбец/таблицу CHARACTER SET utf8mb4 (проверьте с помощью SHOW CREATE TABLE.)
  • <meta charset=UTF-8> в начале HTML
  • Сохраненные процедуры получают текущий набор символов/сопоставлений. Они могут нуждаться в восстановлении.

UTF-8 через

Подробнее о компьютерных языках (и следующих разделах)

Проверьте данные

Просмотр данных с помощью инструмента или с помощью SELECT не может быть доверенным. Слишком много таких клиентов, особенно браузеров, пытаются компенсировать неправильные кодировки и показывают правильный текст, даже если база данных искажена. Итак, выберите таблицу и столбец с неанглийским текстом и выполните

SELECT col, HEX(col) FROM tbl WHERE ...

HEX для правильно сохраненного UTF-8 будет

  • Для пробела (на любом языке): 20
  • Для английского языка: 4x, 5x, 6x или 7x
  • Для большинства стран Западной Европы буквы с акцентом должны быть Cxyy
  • Кириллица, иврит и фарси/арабский: Dxyy
  • Большая часть Азии: Exyyzz
  • Эмодзи и некоторые из китайцев: F0yyzzww
  • Подробнее

Конкретные причины и исправления обнаруженных проблем

Усеченный текст (Se для Señor):

  • Сохраняемые байты не кодируются как utf8mb4. Исправьте это.
  • Также проверьте, что во время чтения установлено UTF-8.

Черные бриллианты с вопросительными знаками (Se�or для Señor); существует один из этих случаев:

Случай 1 (оригинальные байты не были UTF-8):

  • Сохраняемые байты не кодируются как utf8. Исправьте это.
  • Соединение (или SET NAMES) для INSERT и SELECT не было utf8/utf8mb4. Исправьте это.
  • Также убедитесь, что столбец в базе данных - CHARACTER SET utf8 (или utf8mb4).

Случай 2 (оригинальные байты были UTF-8):

  • Соединение (или SET NAMES) для SELECT не было utf8/utf8mb4. Исправьте это.
  • Также убедитесь, что столбец в базе данных CHARACTER SET utf8 (или utf8mb4).

Черные бриллианты появляются только в том случае, если в браузере установлено значение <meta charset=UTF-8>.

Знаки вопроса (обычные, а не черные бриллианты) (Se?or для Señor):

  • Сохраняемые байты не кодируются как utf8/utf8mb4. Исправьте это.
  • Столбец в базе данных не является CHARACTER SET utf8 (или utf8mb4). Почини это. (Используйте SHOW CREATE TABLE.)
  • Также проверьте, что во время чтения установлено UTF-8.

Моджибаке (Señor для Señor): (Это обсуждение также относится к двойному кодированию, которое не обязательно отображается.)

  • Сохраняемые байты должны быть в кодировке UTF-8. Исправьте это.
  • Соединение, когда текст INSERTing и SELECTing должен указывать utf8 или utf8mb4. Исправьте это.
  • Столбец должен быть объявлен как CHARACTER SET utf8 (или utf8mb4). Исправьте это.
  • HTML должен начинаться с <meta charset=UTF-8>.

Если данные выглядят корректно, но не сортируются правильно, то либо вы выбрали неправильное сопоставление, или нет сопоставления, которое соответствует вашим потребностям, или у вас есть двойное кодирование.

Двойное кодирование можно подтвердить с помощью SELECT .. HEX .., описанного выше.

é should come back C3A9, but instead shows C383C2A9
The Emoji 👽 should come back F09F91BD, but comes back C3B0C5B8E28098C2BD

То есть гекс примерно вдвое длиннее, чем должен быть. Это вызвано преобразованием из latin1 (или чего-то еще) в utf8, а затем обработкой байты, как если бы они были latin1 и повторяют преобразование. Сортировка (и сравнение) не работает правильно, потому что, например, сортировка, как если бы строка была Señor.

Исправление данных, где это возможно

Для усечения и знаков вопроса данные теряются.

Для моджибаке/двойного кодирования,...

Для черных бриллиантов,...

(Я должен продолжить это в другом вопросе/ответе.)

Ответ 2

У меня были похожие проблемы с двумя моими проектами после перенастройки сервера. После поиска и опробования многих решений я наткнулся на это:

mysqli_set_charset($con,"utf8");

После добавления этой строки в мой конфигурационный файл все работает отлично!

Я нашел это решение для mysqli https://www.w3schools.com/PHP/func_mysqli_set_charset.asp, когда я искал, чтобы решить вставку из запроса HTML

удачи!

Ответ 3

Забавно, как ты отвечаешь на свой вопрос :)

  1. Установите для своего кода IDE язык UTF8

  2. Добавьте в заголовок вашей веб-страницы, где вы собираете данные формы.

  3. Проверьте, что определение таблицы MySQL выглядит следующим образом:

    CREATE TABLE your_table (
      ...
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8
    
  4. Если вы используете PDO, убедитесь, что

    $options = array(PDO::MYSQL_ATTR_INIT_COMMAND=>'SET NAMES utf8'); 
    $dbL = new PDO($pdo, $user, $pass, $options);
    

Если у вас уже есть большая база данных с указанной выше проблемой, вы можете попробовать экспортировать SIDU с правильной кодировкой и импортировать обратно с UTF8. Удачи

Ответ 4

В зависимости от того, как настроен сервер, вам необходимо соответствующим образом изменить кодировку. utf8 из того, что вы сказали, должно работать лучше всего, но если вы получаете странные символы, это может помочь, если вы измените веб-страницу Кодировать в Ansi. Это помогло мне, когда я создавал PHP MYSQLI, это могло бы помочь вам понять больше https://superuser.com/info/762473/ansi-to-utf-8-in-notepad