MySQL数据似乎不是它应该在的字符编码

时间:2011-09-20 15:58:05

标签: php mysql utf-8 character-encoding pdo

首先,感谢任何人阅读此内容。 我在MySQL数据库中的字符编码有一个非常奇怪的问题,我正在使用PHP的PDO进行交互。这些表都使用UTF8编码,webapp使用utf-8,但似乎存储在数据库中的数据实际上不是utf-8而是latin-1。

在相当长的一段时间内,情况一直很好,但这会导致导入utf-8编码数据文件或进行包含特殊字符(如“é”或“ë”)的全文搜索时出现问题。

修改

有些回复表明这是我终端的问题。它不是:

foreach($dbh->query("SELECT c FROM t") as $row){
    echo $row['c'] ."\n";
    echo urlencode($row['c'])."\n";
}
$dbh->exec("SET NAMES 'latin1'");
foreach($dbh->query("SELECT c FROM t") as $row){
    echo $row['c'] ."\n";
    echo urlencode($row['c'])."\n";
}
$dbh->exec("SET NAMES 'utf8'");
foreach($dbh->query("SELECT c FROM t") as $row){
    echo $row['c'] ."\n";
    echo urlencode($row['c'])."\n";
}

输出以下内容:

é
%C3%A9f
é
%C3%A9f
é
%C3%83%C2%A9f

感谢大家到目前为止。

结束编辑

所以,首先我检查表是否正常工作:

USE information_schema;

mysql> SELECT table_collation FROM tables WHERE table_schema="mydb" and table_name="mytable";
+-----------------+
| table_collation |
+-----------------+
| utf8_general_ci |
+-----------------+
1 row in set (0.00 sec)

mysql> SELECT character_set_name,collation_name FROM information_schema.columns WHERE table_schema="mydb" and table_name="t" and column_name="c";
+--------------------+-----------------+
| character_set_name | collation_name  |
+--------------------+-----------------+
| utf8               | utf8_general_ci |
+--------------------+-----------------+
1 row in set (0.00 sec)

但是,数据似乎不是utf-8,而是latin-1:

mysql> use mydb;
Database changed

mysql> SET NAMES 'latin1';
Query OK, 0 rows affected (0.00 sec)

mysql> select c from t;
+---+
| c |
+---+
| é |
+---+
1 row in set (0.00 sec)

mysql> SET NAMES 'utf8';
Query OK, 0 rows affected (0.00 sec)

mysql> select c from t;
+----+
| c  |
+----+
| é |
+----+
1 row in set (0.00 sec)

所以我有两个问题:

1)最重要的是,我该如何处理数据库中的数据?

2)有没有办法设置数据库,以便实际在连接时使用utf-8,或者每次都必须执行SET NAMES查询?

非常感谢你的时间和帮助,

马特

4 个答案:

答案 0 :(得分:1)

这是你的终端似乎是latin1,而不是数据:)

  

有没有办法设置数据库,以便实际使用utf-8

你已经设置好了。
您唯一需要的是设置客户端编码,这由SET NAMES'utf8'

完成

实际上,通过使用SET NAMES,您可以使您设置的任何编码都显示数据。这是SET NAMES魔术词的唯一目的。

如果您在此问题中未涉及某些编码问题,

  

我该如何处理数据库中的数据?

只要你的数据库没有返回?标记,你就可以随心所欲 要恢复数据,您必须将名称设置为表的数据编码集。这将阻止mysql重新编码数据。所以,您可以获取或转储它,然后使用适当的设置再次加载它。

修改

经过一番考虑之后,我会说你的数据是在utf8中,而表编码以某种方式设置为latin1。

%C3%A9是é角色的完全有效的utf-8表示。 (不知道你在哪里跟踪f

而%C3%83%C2%A9是%C3%A9的utf-f编码版本。因此,您的数据库似乎认为您的数据是在latin1中并在utf8中对其进行编码。

所以,当你将名字设置为latin1时,它不介意也不重新编码。

结论:

  1. 仔细检查您的表(和字段)编码。它应该是latin1

  2. 是的,要保存您的数据,您必须执行

  3. 之类的操作

    * * *上帝我讨厌这个autoformatting问题阻止我在列表项后面发布代码

    mysqldump --default_charset=latin1 mydb > mydb.sql
    

    然后检查此转储并将latin1的每个外观更改为utf8 然后加载回来。

    不要忘记先备份您的数据!

答案 1 :(得分:-1)

如果您从HTML网页收到数据并将其保存到您的数据库,请不要忘记在HTML的head部分中设置正确的文字编码:

  <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"/>

如果您没有设置文本编码,浏览器可能会返回不同编码的文本。

关于1):看看PHP的

string utf8_decode ( string $data )

功能描述here。从数据库中检索记录,转码为所需的编码并将其写回。

答案 2 :(得分:-1)

使用

SET character_set_client = "UTF-8";

与客户联系时。在PHP中,您将通过使用函数来实现此目的:

set_charset($encoding)
在进行任何实际数据插入/更新之前

答案 3 :(得分:-1)

  1. 连接到您的数据库

  2. 设置与UTF-8的连接

    SET NAMES'utf8';

  3. 在您的HTML文件中:

    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />