Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/288.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/65.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 如何更正MySQL utf8\u general\u ci字段中的双编码UTF-8字符串?_Php_Mysql_Utf 8 - Fatal编程技术网

Php 如何更正MySQL utf8\u general\u ci字段中的双编码UTF-8字符串?

Php 如何更正MySQL utf8\u general\u ci字段中的双编码UTF-8字符串?,php,mysql,utf-8,Php,Mysql,Utf 8,我必须重新设计一个类,其中UTF-8字符串被错误地双重编码: $string = iconv('ISO-8859-1', 'UTF-8', $string); : $string = utf8_encode($string); 这些错误字符串已保存到MySQL数据库中的多个表字段中。所有受影响的字段都使用排序规则utf8\u general\u ci 通常我会设置一个小PHP补丁脚本,在受影响的表中循环,选择记录,通过在双编码字段上使用utf8\u decode()纠正错误记录并更新它们 由于

我必须重新设计一个类,其中UTF-8字符串被错误地双重编码:

$string = iconv('ISO-8859-1', 'UTF-8', $string);
:
$string = utf8_encode($string);
这些错误字符串已保存到MySQL数据库中的多个表字段中。所有受影响的字段都使用排序规则
utf8\u general\u ci

通常我会设置一个小PHP补丁脚本,在受影响的表中循环,选择记录,通过在双编码字段上使用
utf8\u decode()
纠正错误记录并更新它们

由于这次我得到了很多巨大的表格,而错误只影响到德国umlauts(äöüßÄÜ),我想知道是否有比这更聪明/更快的解决方案

像下面这样的纯MySQL解决方案安全且值得推荐吗

 UPDATE `table` SET `col` = REPLACE(`col`, 'ä', 'ä');

任何其他解决方案/最佳实践?

MySQL提供了一个regexp匹配,但没有regexp替换,因此您通常最好遍历php中的每一行,根据需要进行转换,并在行发生更改时更新该行。

MySQL支持字符集,因此您可以在SQL中进行转换。但对于这种情况,我可能更喜欢用PHP编写脚本,因为这是一项一次性任务

请记住,MySql中的列有一个字符集属性。排序规则(理论上)与字符集正交。虽然
utf8\u general\u ci
排序意味着字符集是
utf8
,但它不是给定的。从理论上讲,您可以将utf8排序规则与拉丁1编码混合使用(从而得到垃圾)

如果您决定在SQL中执行此操作,请查看以下内容:


更改表格,将列字符集更改为Latin-1。现在,您将拥有单独编码的UTF-8字符串,但位于排序规则应为Latin-1的字段中

然后,通过二进制字符集将列字符集更改回UTF-8,这样MySQL在任何时候都不会转换字符

ALTER TABLE MyTable MODIFY MyColumn ... CHARACTER SET latin1
ALTER TABLE MyTable MODIFY MyColumn ... CHARACTER SET binary
ALTER TABLE MyTable MODIFY MyColumn ... CHARACTER SET utf8

(是正确的语法iirc;将适当的列类型放在
所在的位置)

使用mysqldump生成转储,更改编码声明(在第一个命令中),然后重新加载到另一个数据库中

您还可以在转储中使用iconv对其进行转码


您可以选择输入输出文件,使用php或iconv对文件进行处理,然后加载数据填充。

我尝试了发布的解决方案,但我的数据库不断出现错误。最终我偶然发现了以下解决方案(我相信是在一个论坛上,但我不记得在哪里):

这是一种享受。希望这能帮助像我一样在绝望的谷歌搜索中跌跌撞撞的人


注意:这当然是假设您的双重编码字符问题源于从latin1到utf8的非常有用的MySQL转换,但我相信这就是大多数“损坏字符”发生的地方。这与上面提到的转换基本相同,先转换为拉丁语1,然后转换为二进制,再转换为utf8(使用二进制步骤作为防止已编码拉丁语1实体重新编码的方法)

我发现以下方法更简单:

mysqldump -h DB_HOST -u DB_USER -p --skip-set-charset --default-character-set=latin1 DB_NAME > DB_NAME-dump.sql
然后删除所有表并使用以下命令重新导入:

mysql -h DB_HOST -u DB_USER -p --default-character-set=utf8 DB_NAME < DB_NAME-dump.sql
mysql-hdb\u HOST-udb\u USER-p——默认字符集=utf8 DB\u NAME
在以下URL找到提示:

我本想对整个转储进行
utf8\u解码,但还是放弃了。只是因为有些表太大了(每个表1G以上),这会迫使我逐行读取和转换整个转储文件。无论如何谢谢。老实说,直到你在第二段提到它之前,我一直认为排序规则
utf8\u general\u ci
同时意味着字符集
utf8
+感谢我在几十年后再次阅读MySQL基本文档(这次更仔细^^)。非常感谢你的帮助。哦。。这一次真的把我从椅子上砸了下来(双关语)!谢谢你从你的魔法包里拿出这个。它起到了很好的作用,消除了我对“记忆不足”问题的担忧。我只需要使用
CHANGE
而不是
MODIFY
。顺便说一句,我注意到切换到charset
latin1
会隐式地将排序规则切换到
latin1\u swedish\u ci
。附加
校对拉丁文1\u瑞典语ci
来强制这样做会更安全吗?同样适用于
二进制
(将排序规则切换为
)和
utf8
(将排序规则切换回
utf8\u常规\u ci
)。再次感谢你。您保存了my night^^^我想每次更改字符集时,如果未指定排序规则,则排序规则将成为新字符集的默认排序规则。排序规则对于前两个更改不重要,因为您只是临时使用该字符集,并且排序规则对字符在表中的存储方式或存储的字符没有任何影响。只有编码在这两个变化中起作用。因此,您应该只需要为最终更改指定排序规则,即将其更改回UTF-8的排序规则。但是,如果我错了,我欢迎被纠正。谢谢你进一步阐述这一点。在MySQL文档中找到一个页面,确认您对回退的想法。强制对最后一个开关进行排序对我来说也是有意义的。将这样做。跳过第一个ALTER
——这是不必要的,可能会损坏数据。如果跳过第一个ALTER命令,那么这些命令将不会产生任何净效果。您只需将MySQL服务器绑定一段时间,同时对列定义进行更改,然后再次直接更改。你能详细说明一下你关于数据可能被“损坏”的说法吗?潜在损害的性质是什么?此解决方案比其他解决方案更简单、速度更快。这非常有效。。。在双编码列上。它搞乱了我所有的正确编码的列(不要问),把所有的西里尔文都改成了。通过复制t易于修复
mysql -h DB_HOST -u DB_USER -p --default-character-set=utf8 DB_NAME < DB_NAME-dump.sql