将 UTF8 表上的 latin1 字符转换为 UTF8

直到今天,我才意识到我在PHP脚本中缺少这个:

mysql_set_charset('utf8');

我所有的表都是InnoDB,排序规则“utf8_unicode_ci”,我所有的VARCHAR列也是“utf8_unicode_ci”。我有我的PHP脚本,我所有的PHP文件都被编码为UTF-8。mb_internal_encoding('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 &aacute; (á)ţă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'].'"');
}

它“UPDATE”与预期的字符,除了字符串在字符“ă”之后被截断。我的意思是,字符串中不包含该字符和后面的字符。

此外,使用“iconv()”(在代码上注释)进行测试也是如此,即使使用 //IGNORE 和 //TRANSLIT 也是如此

我还测试了ISO-8859-1和ISO-8859-15之间的几个字符集。


答案 1

从您描述的内容来看,您似乎有 UTF-8 数据,这些数据最初存储为 Latin-1,然后未正确转换为 UTF-8。数据是可恢复的;你需要一个MySQL函数,比如

convert(cast(convert(name using  latin1) as binary) using utf8)

您可能需要省略内部转换,具体取决于编码转换期间数据的变化方式。


答案 2

在我搜索了大约一两个小时的这个答案之后,我需要将旧的tt_news数据库从拼写错误迁移到新的typo3版本。我试图转换导出文件中的字符集并将其导入回去,但没有让它工作。

然后,我从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

如果需要,您还可以转换图像标题,图像alttext,图像标题文本和关键字。希望这将有助于有人tt_news迁移到新的typo3版本。


推荐