将 UTF8 表上的 latin1 字符转换为 UTF8
Posted
技术标签:
【中文标题】将 UTF8 表上的 latin1 字符转换为 UTF8【英文标题】:Convert latin1 characters on a UTF8 table into UTF8 【发布时间】:2012-03-13 13:12:41 【问题描述】:直到今天我才意识到我的 php 脚本中缺少这个:
mysql_set_charset('utf8');
我所有的表都是 InnoDB,排序规则“utf8_unicode_ci”,我所有的 VARCHAR 列也是“utf8_unicode_ci”。我的 PHP 脚本中有mb_internal_encoding('UTF-8');
,我所有的 PHP 文件都编码为 UTF-8。
所以,直到现在,每次我“插入”带有变音符号的东西时,例如:
mysql_query('INSERT INTO `table` SET `name`="Jáuò Iñe"');
在本例中,“名称”内容为:Jáuò Iñe
。
由于我修复了 PHP 和 MySQL 之间的字符集,新的 INSERT 现在可以正确存储。但是,我想修复目前“混乱”的所有旧行。我已经尝试了很多东西,但它总是会破坏第一个“非法”字符的字符串。这是我当前的代码:
$m = mysql_real_escape_string('¿<?php echo "¬<b>\'PHP á (á)ţăriîş </b>"; ?> ă-ţi abcdd;//;ñç´พดแทฝใจคçăâξβψδπλξξςαยนñ ;');
mysql_set_charset('utf8');
mysql_query('INSERT INTO `table` SET `name`="'.$m.'"');
mysql_set_charset('latin1');
mysql_query('INSERT INTO `table` SET `name`="'.$m.'"');
mysql_set_charset('utf8');
$result = mysql_iquery('SELECT * FROM `table`');
while ($row = mysql_fetch_assoc($result))
$message = $row['name'];
$message = mb_convert_encoding($message, 'ISO-8859-15', 'UTF-8');
//$message = iconv("UTF-8", "ISO-8859-1//IGNORE", $message);
mysql_iquery('UPDATE `table` SET `name`="'.mysql_real_escape_string($message).'" WHERE `a1`="'.$row['a1'].'"');
它使用预期的字符“更新”,除了字符串在字符“ă”之后被截断。我的意思是,该字符和后面的字符不包含在字符串中。
此外,使用“iconv()”(在代码上注释)进行测试也是如此,即使使用 //IGNORE 和 //TRANSLIT
我还测试了几个字符集,介于 ISO-8859-1 和 ISO-8859-15 之间。
【问题讨论】:
【参考方案1】:根据您的描述,您似乎有最初存储为 Latin-1 的 UTF-8 数据,然后没有正确转换为 UTF-8。数据可恢复;你需要一个像
这样的 MySQL 函数convert(cast(convert(name using latin1) as binary) using utf8)
您可能需要省略内部转换,具体取决于编码转换期间数据的更改方式。
【讨论】:
哇,你拯救了我的一天!我从未使用过这些功能,现在在 UPDATE 上使用并且它有效。非常感谢! 谢谢!我已经构建了一个小的 php 脚本,它遍历每个表中的所有列。成功了吗:) 非常感谢 ABS!!!!很多相关的 SO 问题,但只有这一个包含正确转换为 UTF-8 的功能 您的回答对我的修复很有帮助。谢谢 5 年多后,这个很棒的答案让我免于心痛。你简直太棒了。但是,我有一个问题:如果要转换的列很多,通配符可以代替名称吗?【参考方案2】:在我搜索了大约一两个小时来寻找这个答案之后,我需要将一个旧的 tt_news 数据库从打字错误迁移到一个新的打字错误版本。我尝试转换导出文件中的字符集并将其导入回来,但没有得到它的工作。
然后我从 ABS 尝试了上面的答案,并开始在桌子上更新:
UPDATE tt_news SET
title=convert(cast(convert(title using latin1) as binary) using utf8),
short=convert(cast(convert(short using latin1) as binary) using utf8),
bodytext=convert(cast(convert(bodytext using latin1) as binary) using utf8)
WHERE 1
如果需要,您还可以转换 imagecaption、imagealttext、imagetitletext 和关键字。 希望这将有助于有人将 tt_news 迁移到新的typo3 版本。
【讨论】:
在我找到你的答案之前,我没有得到 ABS 的答案。 确实,ABS 的答案是答案的“关键”。马塞尔的回答在一个完整的例子中使用了那个“钥匙”。两个都投赞成票! 赞成任何跨数据库导出/导入的关键查询。拯救了我的一天!【参考方案3】:方法更好 使用连接拖你的数据库正常
然后使用此代码来制作您需要的东西 您必须在 header cod html 中通过 meta 使您的页面编码 utf-8(不要忘记这一点)
然后使用此代码
$result = mysql_query('SELECT * FROM shops');
while ($row = mysql_fetch_assoc($
$name= iconv("windows-1256", "UTF-8", $row['name']);
mysql_query("SET NAMES 'utf8'");
mysql_query("update `shops` SET `name`='".$name."' where ID='$row[ID]' ");
【讨论】:
这不是更好,而且当名称第一次包含撇号时,您的方式就会中断。另外,为什么要为每一行执行“SET NAMES”?【参考方案4】:我强烈建议使用 'utf8mb4' 而不是 'utf8',因为 utf8 不能存储一些汉字和表情符号。
【讨论】:
True,但不是问题的答案。以上是关于将 UTF8 表上的 latin1 字符转换为 UTF8的主要内容,如果未能解决你的问题,请参考以下文章
数据库从 latin1 到 utf8mb4 的转换,索引呢?