PHP / MySQL: исправление текста utf8, поврежденного неявным соединением mysqli :: set_charset (‘latin1’)

Итак, на протяжении многих лет мое PHP-приложение подключалось к MySQL по умолчанию latin1 кодировок. Хотя у меня есть некоторые поля, сопоставленные как utf8_general_ciфактические данные, которые хранятся в них, представляют собой некоторую убогую кодировку. Например:

Входные данные: ♠ »

хранится как ♠»

Теперь, когда эти данные получены по тому же latin1 подключения и отображается на странице с кодировкой, установленной как utf8, он отображается так же, как он был введен: ♠ » Почему это так, я не уверен на 100%, но я предполагаю, что это потому, что любая функция кодировки, которая запутывает ее, исправляет ее.

Я хочу исправить свои данные. Если я переключаю свою кодировку соединения, используя mysqli::set_charset('utf8')выходные данные отображаются в том виде, в котором они сохранены, т.е. ♠»

Итак, по-видимому, мне нужно исправить существующие данные и затем переключить кодировку подключения.

Как я могу исправить существующие убитые данные?

РЕДАКТИРОВАТЬ:

Я обнаружил способ подражать процессу коррупции, который
происходит в запросе MySQL: SELECT CAST(BINARY '♠ »' AS CHAR CHARACTER SET latin1) выходы ♠»

Возможно, если бы я мог понять, как выполнить обратную функцию, я мог бы использовать этот запрос для исправления существующих данных.

РЕДАКТИРОВАТЬ 2:

Я обнаружил такую ​​функцию: SELECT CAST(BINARY CAST('♠»' AS CHAR CHARACTER SET latin1) AS CHAR CHARACTER SET utf8) выходы ♠ »

Сейчас меня беспокоит только то, что это будет делать с любыми данными, которые уже
случается фактические данные utf8, которые, по некоторым причинам, у меня есть в
моя база данных Например, SELECT CAST(BINARY CAST('♠ »' AS CHAR CHARACTER SET latin1) AS CHAR CHARACTER SET utf8) выходы (ничего)

1

Решение

От http://jonisalonen.com/2012/fixing-doubly-utf-8-encoded-text-in-mysql/:

Функция автоопределения для преобразования возможно испорченных латинских текстовых данных в utf8:

DELIMITER $$

CREATE FUNCTION maybe_utf8_decode(str text charset utf8)
RETURNS text CHARSET utf8 DETERMINISTIC
BEGIN
declare str_converted text charset utf8;
declare max_error_count int default @@max_error_count;
set @@max_error_count = 0;
set str_converted = convert(binary convert(str using latin1) using utf8);
set @@max_error_count = max_error_count;
if @@warning_count > 0 then
return str;
else
return str_converted;
end if;
END$$

DELIMITER ;

Использование:

update mytable set mycolumn = maybe_utf8_decode(mycolumn);
1

Другие решения

Прежде чем пытаться «исправить» данные, убедитесь, что у вас есть. SELECT col, HEX(col) ... может быть 3 байта: E299A0или это может быть больше: C3A2 E284A2 C2A0, Первым является Мохибаке; последний является «двойным кодированием». Ремонт разные. Больше обсуждения Вот а также Вот.

1

По вопросам рекламы [email protected]