Итак, на протяжении многих лет мое 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)
выходы (ничего)
От 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);