PHP / MySQL:修复由隐式mysqli :: set_charset(' latin1')连接损坏的utf8文本

时间:2016-09-01 02:37:11

标签: php mysql utf-8 character-encoding iso-8859-1

因此,多年来,我的PHP应用程序一直使用默认的latin1字符集连接到MySQL。即使我将一些字段整理为utf8_general_ci,但存储在其中的实际数据仍然是一些混淆的字符集。例如:

输入:♠ »

存储为♠»

现在,当通过相同的latin1连接检索该数据并将其显示在编码设置为utf8的网页上时,它会显示为输入的内容:♠ »为什么这是,我不是百分百肯定,但我猜它是因为无论是什么字符集功能搞砸了它都会解决它。

我想修复我的数据。如果我使用mysqli::set_charset('utf8')切换连接字符集,则输出会在存储时显示,即♠»

所以,显然我需要修复现有数据,然后切换连接字符集。

如何修复现有的bastardized数据?

编辑:

  

我发现了一种模仿腐败过程的方法   发生在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)输出(无)

2 个答案:

答案 0 :(得分:1)

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

自动检测功能,用于将可能已损坏的latin1文本数据转换为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 :(得分:1)

在尝试"修复"数据,确保你拥有的。 SELECT col, HEX(col) ... - 可能是3个字节:E299A0,或者可能更多:C3A2 E284A2 C2A0。前者是Mojibake;后者是"双重编码"。修理是不同的。更多讨论herehere