Проблемы с символами UTF-8; то, что я вижу, не то, что я храню
Я попытался использовать UTF-8 и столкнулся с проблемой.
Я перепробовал так много вещей; Вот результаты, которые я получил:
????
вместо азиатских символов. Даже для европейского текста я получилSe?or
заSeñor
,- Странная тарабарщина (моджибаке), такая как
Señor
или же新浪新闻
за新浪新闻
, - Черные бриллианты, такие как Se or.
- Наконец, я попал в ситуацию, когда данные были потеряны или, по крайней мере, обрезаны:
Se
заSeñor
, - Даже когда я заставил текст выглядеть правильно, он не сортировался правильно.
Что я делаю неправильно? Как я могу исправить код? Могу ли я восстановить данные, если да, то как?
3 ответа
Эта проблема мучает участников этого сайта и многих других.
Вы перечислили пять основных случаев 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
Подробнее о компьютерных языках (и следующих разделах)
Проверьте данные
Просмотр данных с помощью инструмента или с 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
,
Исправление данных, где это возможно
Для усечения и вопросительных знаков данные теряются.
Для моджибаке / двойного кодирования,...
Для черных бриллиантов...
(Я должен продолжить это в другом вопросе / ответе.)
У меня были похожие проблемы с двумя моими проектами после перенастройки сервера. После поиска и опробования многих решений я наткнулся на это:
mysqli_set_charset($con,"utf8");
После добавления этой строки в мой конфигурационный файл все работает отлично!
Я нашел это решение для mysqli https://www.w3schools.com/PHP/func_mysqli_set_charset.asp когда я искал, чтобы решить вставку из запроса HTML
удачи!
Я тоже искал ту же проблему, мне потребовался почти 1 месяц, чтобы найти подходящее решение. Прежде всего, вам нужно будет обновить свою базу данных, чтобы все последние CHARACTER и COLLATION до utf8mb4 или, по крайней мере, поддерживали данные utf-8.
Для Java:
при создании соединения JDBC добавьте это в URL-адрес соединения useUnicode=yes и characterEncoding=UTF-8 в качестве параметров, и он будет работать.
Для питона:
Перед запросом в базу данных попробуйте применить это к курсору *cursor.execute('SET NAMES utf8mb4')
cursor.execute("SET CHARACTER SET utf8mb4")
cursor.execute("SET character_set_connection=utf8mb4")
*
Если это не сработает, удачной охоты за правильным решением.
Забавно, как ты отвечаешь на свой вопрос:)
Установите для своего кода IDE язык UTF8
Добавьте в заголовок вашей веб-страницы, где вы собираете данные формы.
Проверьте, что определение таблицы MySQL выглядит следующим образом:
CREATE TABLE your_table ( ... ) ENGINE=InnoDB DEFAULT CHARSET=utf8
Если вы используете PDO, убедитесь, что
$options = array(PDO::MYSQL_ATTR_INIT_COMMAND=>'SET NAMES utf8'); $dbL = new PDO($pdo, $user, $pass, $options);
Если у вас уже есть большая база данных с вышеуказанной проблемой, вы можете попробовать экспортировать SIDU с правильной кодировкой и импортировать обратно с UTF8. Удачи
В зависимости от того, как настроен сервер, вы должны соответственно изменить кодировку. utf8 из того, что вы сказали, должен работать лучше, однако, если вы получаете странные символы, это может помочь, если вы измените веб-страницу Encode на Ansi. Это помогло мне, когда я настраивал PHP MYSQLI, это может помочь вам понять больше https://superuser.com/questions/762473/ansi-to-utf-8-in-notepad