系统是访问MySQL数据库的PHP应用程序。第一个表是使用标准的latin1编码创建的,并通过PHP中的mysqli填充,而不设置任何编码。 PHP脚本和数据都以UTF-8工作。
较新的表格已将编码设置为utf8_bin,并且在每个事务SET CHARACTER SET utf8
之前都会发送。
如果我查看mysql数据库中的较新表(通过像HeidiSQL这样的sql explorer),每个特殊字符都会正确显示。但是,在每个旧表中,典型的latin1-utf8错误都可见,如ü为ü。
是否可以通过以下方式之一轻松解决此问题:
SET CHARACTER SET utf8
或latin1
,使表编码符合要求(仅仅是一种解决方法)SET CHARACTER SET utf8
必须在每个mysqli连接的开头发送(或者可能有办法将其设置为标准?)SET CHARACTER SET utf8
,但在数据库资源管理器中编码错误。似乎数据库将所有表格都视为utf8并显示latin1表格因此错误的字符。如果没有说出不同的话,Mysqli会将所有表格作为latin1。
应用程序非常高效,编码问题对用户不可见,因为正确的编码会在每个语句前面告诉mysqli。但我觉得这不是一个好习惯。
我认识到数据库的设置方式存在问题,我希望了解解决此问题的最佳做法。
答案 0 :(得分:0)
第一个表是使用标准的latin1编码创建的,并通过PHP中的mysqli填充
所以,那些表有垃圾。你需要恢复数据吗?
在每个交易前面发送SET CHARACTER SET utf8。
那没用。相反,请在连接后执行SET NAMES utf8
。
Ü
是Ü
的Mojibake。在这个论坛搜索Mojibake。
有一些表latin1与utf8字节,而其他表是utf8 - 这将是一个痛苦的混乱继续。现在停下来清理乱七八糟的东西。一直走到utf8。
Mojibake摘要:
SET NAMES latin1
(或set_charset('latin1')
或...)相关联。 (应该是utf8
。)CHARACTER SET latin1
。 (或者它可能是从表/数据库继承的。)(应该是utf8
。)CHARACTER SET utf8
,也可能不是ALTER TABLE Tbl MODIFY COLUMN col VARBINARY(...) ...;
ALTER TABLE Tbl MODIFY COLUMN col VARCHAR(...) ... CHARACTER SET utf8 ...;
,但应该是这样。如果您需要修复数据,则需要“两步更改”,例如
{{1}}
答案 1 :(得分:0)
好的,您不能使用mysqldump创建带有相关表的.sql文件,因为它会为您提供与HeidiSQL相同的垃圾字符。
但您可以使用PHP脚本执行此操作,使用与PHP应用程序中相同的错误字符集创建.sql文件。该PHP脚本应该执行以下操作:
mb_internal_encoding("UTF-8");
$link = mysqli_connect('localhost', 'root', '');
mysqli_set_charset($link, "latin1");
$result = mysqli_query($link, "SELECT * FROM table1", MYSQLI_USE_RESULT);
while($row = mysqli_fetch_assoc($result))
{
# Generate INSERT statements for table1 using some PHP logic, and write these into a new file, named e.g. fixencoding.sql
}
mysqli_free_result($result);
mysqli_query($link, "DELETE * FROM table1");
mysqli_query($link, "ALTER TABLE table1 COLLATE='utf8_general_ci'");
$result = mysqli_query($link, "SELECT * FROM table2", MYSQLI_USE_RESULT);
while($row = mysqli_fetch_assoc($result))
{
# Generate INSERT statements for table2 and append these into the .sql file created above
}
mysqli_free_result($result);
mysqli_query($link, "DELETE * FROM table2");
mysqli_query($link, "ALTER TABLE table2 COLLATE='utf8_general_ci'");
# etc. - repeat above steps for every broken table
mysqli_close($link);
创建的fixencoding.sql文件现在是一个没有BOM的utf-8编码文件,您可以使用mysql.exe导入该文件:
C:\path\to\mysql\bin\mysql.exe -hlocalhost -uroot name-of-database <fixencoding.sql
如果一切顺利,您的PHP应用程序应包含正确的MySQL字符集:
mysqli_set_charset($link, 'utf8');
此外,HeidiSQL和其他客户端应该显示真正的utf-8字符。
这都没有经过测试!不要忘记先通过注释DELETE和ALTER查询来进行干运行!