我必须重新设计一个类,其中(其中包括)UTF-8字符串被错误地双重编码:
$string = iconv('ISO-8859-1', 'UTF-8', $string);
:
$string = utf8_encode($string);
Run Code Online (Sandbox Code Playgroud)
这些错误的字符串已保存到MySQL数据库的多个表字段中.受影响的所有字段都使用整理utf8_general_ci.
通常我会设置一个小的PHP补丁脚本,循环通过受影响的表,选择记录,通过使用utf8_decode()双编码字段更正错误记录并更新它们.
因为这次我得到了很多很大的桌子,这个错误只会影响德国变音符号(äöüßÄÖÜ),我想知道是否有更智能/更快的解决方案.
纯粹的MySQL解决方案是否安全且值得推荐?
UPDATE `table` SET `col` = REPLACE(`col`, 'ä', 'ä');
Run Code Online (Sandbox Code Playgroud)
任何其他解决方案/最佳实践?
Ham*_*ite 20
更改表以将列字符集更改为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
Run Code Online (Sandbox Code Playgroud)
(是正确的语法iirc;将适当的列类型放在where ...)
Owe*_*ing 13
我尝试了发布的解决方案,但我的数据库不断吐出错误.最终我偶然发现了以下解决方案(在我认为的论坛中,但我不记得在哪里):
UPDATE table_name SET col_name = CONVERT(CONVERT(CONVERT(col_name USING latin1) USING binary) USING utf8);
Run Code Online (Sandbox Code Playgroud)
它是一种享受.希望这有助于任何人在这里偶然发现像我一样的绝望谷歌搜索.
注意:这当然是假设您的双重编码字符问题源于从latin1到utf8的过度有用的MySQL转换,但我相信大多数这些"损坏的字符"都会发生.这基本上做了与上面提到的相同的转换回到latin1,然后二进制,然后到utf8(使用二进制步骤作为防止已编码的latin1实体的重新编码的方式)
小智 7
我发现以下方法更简单:
mysqldump -h DB_HOST -u DB_USER -p --skip-set-charset --default-character-set=latin1 DB_NAME > DB_NAME-dump.sql
Run Code Online (Sandbox Code Playgroud)
然后删除所有表并使用以下命令重新导入:
mysql -h DB_HOST -u DB_USER -p --default-character-set=utf8 DB_NAME < DB_NAME-dump.sql
Run Code Online (Sandbox Code Playgroud)
在此URL上找到了提示:http: //blog.hno3.org/2010/04/22/fixing-double-encoded-utf-8-data-in-mysql/