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

PHP/MySQL:修复被隐式mysqli::set_charset('latin1')连接损坏的utf8文本,php,mysql,utf-8,character-encoding,iso-8859-1,Php,Mysql,Utf 8,Character Encoding,Iso 8859 1,因此,多年来,我的PHP应用程序一直使用默认的latin1字符集连接到MySQL。尽管我有一些字段被整理为utf8\u general\u ci,但存储到其中的实际数据是一些非标准化的字符集。例如: 输入:♠ » 存储为-™ » 现在,当通过相同的latin1连接检索该数据并将其显示在编码设置为utf8的页面上时,其显示方式与输入时相同:♠ »为什么会这样,我不是100%确定,但我猜这是因为不管是什么字符集函数把它搞砸了,都会把它修好 我想修正我的数据。如果我使用mysqli::set_cha

因此,多年来,我的PHP应用程序一直使用默认的latin1字符集连接到MySQL。尽管我有一些字段被整理为utf8\u general\u ci,但存储到其中的实际数据是一些非标准化的字符集。例如:

输入:♠ »

存储为-™ »

现在,当通过相同的latin1连接检索该数据并将其显示在编码设置为utf8的页面上时,其显示方式与输入时相同:♠ »为什么会这样,我不是100%确定,但我猜这是因为不管是什么字符集函数把它搞砸了,都会把它修好

我想修正我的数据。如果我使用mysqli::set_charset'utf8切换连接字符集,则输出将显示为存储状态,即–™ »

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

如何修复现有的bastardized数据

编辑:

我发现了一种模拟腐败过程的方法 在MySQL查询中发生:选择CASTBINARY'♠ »“作为字符集拉丁1输出”™ »

也许,如果我能弄清楚如何执行反向函数,我可以使用该查询来修复现有数据

编辑2:

我发现了这样一个函数:SELECT castbarial CAST–™ »“作为字符字符集拉丁1作为字符字符集utf8输出”♠ »

我现在唯一关心的是,这将对任何已经存在的数据产生什么影响 碰巧是实际的utf8数据,出于某种原因,我在 我的数据库。例如,选择CASTBINARY CAST'♠ »“AS CHAR字符集latin1 AS CHAR字符集utf8不输出任何内容

发件人:

自动检测功能,用于将1文本数据转换为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);

在尝试修复数据之前,请确保您拥有什么。选择col,HEXcol…-♠ 可能是3个字节:E299A0,也可能更多:C3A2 E284A2 C2A0。前者是莫吉贝克;后者是双重编码。修理是不同的。更多的讨论和讨论。

这里讨论的字段的字符集已经是utf8\u general\u ci。问题是存储的数据似乎已损坏,因为连接已被latin1maybe mysqldump和转换?或者至少是受影响的表-我不认为您的实际SQL命令会受到影响。但是,我不确定转换将是什么。我真的不确定存储数据的字符集是什么。请将其视为拉丁文1并转换为utf8_general_ciI。我喜欢使用函数修复编码不正确的数据,并在备份后进行了尝试。但是,当我运行MySQL客户端时,它在第4*行的列“str”中给出了一个错误,*SQL错误1366:不正确的字符串值:'\xA0 Ther…'。