3 回答
MarcB 的评论完全正确 - 每一层的编码必须相同。要对此进行调试,您将需要找出哪个层的编码不正确。
做这个:
搜索您的 PHP 源代码并找到执行实际调用以从 MySQL 中选择内容的行。
此时,对字符串进行十六进制编码并查看原始字节是什么。例如:
// temp, debugging
print("TEST:".bin2hex($whatever_field_value));
die();
看看你得到了什么。正确编码的左 UTF-8“智能报价”将给出:e2809c
. 如果它改为给你一个字节或其他值,那么它不是 UTF-8。此时您会知道编码问题存在于 PHP mysqli 调用和数据库之间(检查 mysql 字段的字符集,如果有任何明确设置,表的默认字符集和连接的字符集 - 请参阅mysqli_set_charset )
(注意:您可以通过将字符保存为 UTF-8 文本文件,然后使用任何二进制编辑器或hexdump -C
在 Mac/Linux 上打开它来轻松查看字符的 UTF-8 编码。[注意 UTF-8 字节顺序马克 - efbbbf
- 一些编辑放在文件的前面,这不是你要找的,忽略它])
如果此时正确,则在文本输出之前再次执行相同的测试(可能在 Joomla 模板文件之一中)。看看那里是否正确。
然后在浏览器级别对其进行测试,wget(或 curl 或其他)页面:
wget http://yoursitename/ -O test.html
对结果执行hexdump -C
(或在二进制编辑器中打开)并找到该引用的位置并查看原始字节是什么。
如前所述,Content-type HTTP 标头和 meta content-type 标签需要匹配您使用的编码 (UTF-8) - 所以也要检查一下(wget -S
将显示标头)。但是,请意识到不仅您的标头和元标记需要使用 UTF-8,而且数据实际上必须编码为 UTF-8 - 这就是您需要按上述方式检查它的原因。
这将告诉您缩小问题范围需要知道什么,此时您可能已经知道需要做什么来修复,或者至少知道设置的哪个特定部分导致了问题。
尝试在其他任何事情之前运行此查询:
mysql_query("SET NAMES 'utf8'");
上次我遇到字符集问题是因为即使其他所有内容都是 UTF-8(提供的 HTML、我编写的代码、数据库表等),数据库连接仍然在另一个字符集中传递所有内容. 这应该解决这个问题。
编辑:正如下面@null.point3r 所提到的,使用以下代码是一个更好的选择,因为转义字符串可能仍然使用错误的编码:
$mysqli->set_charset('utf8')
首先你需要导出你当前的数据库,让我们这样做
# mysqldump -uroot -p databasename > database.sql
然后您需要将您的 latin1 数据转换为 utf8,让我们这样做
# iconv -f 'latin1' -t 'utf-8' database.sql > database_utf8.sql
然后,导入数据回来
# mysql -uroot -p databasename < database_utf8.sql
由于您已经处理了输出编码和 mysql 连接/整理,您应该看到通过您的 apache 提供的正确字符:)