Board logo

标题: MySQL中文乱码,phpmyadmin乱码,php乱码 产生原因及其解决方法 [打印本页]

作者: 我不是鱼    时间: 2006-8-2 19:30     标题: MySQL中文乱码,phpmyadmin乱码,php乱码 产生原因及其解决方法

近日发现很多人为MySQL中文乱码问题所困扰。于是就这个问题做一下浅析。不正确的地方希望大家指正
更多数据库知识请参考 http://www.phpfans.net/view.php?id=4

/*
作者:我不是鱼
网址:http://www.phpfans.net
博客:http://www.phpfans.net/space/index.php/2
email:deng5765@163.com
*/


乱码产生原因

mysql字符编码是版本4.1引入的,支持多国语言,而且一些特性已经超过了其他的数据库系统。

我们可以在MySQL Command Line Client 下输入如下命令查看mysql的字符集

mysql> SHOW CHARACTER SET;
+----------+-----------------------------+---------------------+--------+
| Charset  | Description                 | Default collation   | Maxlen |
+----------+-----------------------------+---------------------+--------+
| big5     | Big5 Traditional Chinese    | big5_chinese_ci     | 2      |
| dec8     | DEC West European           | dec8_swedish_ci     | 1      |
| cp850    | DOS West European           | cp850_general_ci    | 1      |
| hp8      | HP West European            | hp8_english_ci      | 1      |
| koi8r    | KOI8-R Relcom Russian       | koi8r_general_ci    | 1      |
| latin1   | cp1252 West European        | latin1_swedish_ci   | 1      |
| latin2   | ISO 8859-2 Central European | latin2_general_ci   | 1      |
| swe7     | 7bit Swedish                | swe7_swedish_ci     | 1      |
| ascii    | US ASCII                    | ascii_general_ci    | 1      |
| ujis     | EUC-JP Japanese             | ujis_japanese_ci    | 3      |
| sjis     | Shift-JIS Japanese          | sjis_japanese_ci    | 2      |
| hebrew   | ISO 8859-8 Hebrew           | hebrew_general_ci   | 1      |
| tis620   | TIS620 Thai                 | tis620_thai_ci      | 1      |
| euckr    | EUC-KR Korean               | euckr_korean_ci     | 2      |
| koi8u    | KOI8-U Ukrainian            | koi8u_general_ci    | 1      |
| gb2312   | GB2312 Simplified Chinese   | gb2312_chinese_ci   | 2      |
| greek    | ISO 8859-7 Greek            | greek_general_ci    | 1      |
| cp1250   | Windows Central European    | cp1250_general_ci   | 1      |
| gbk      | GBK Simplified Chinese      | gbk_chinese_ci      | 2      |
| latin5   | ISO 8859-9 Turkish          | latin5_turkish_ci   | 1      |
| armscii8 | ARMSCII-8 Armenian          | armscii8_general_ci | 1      |
| utf8     | UTF-8 Unicode               | utf8_general_ci     | 3      |
| ucs2     | UCS-2 Unicode               | ucs2_general_ci     | 2      |
| cp866    | DOS Russian                 | cp866_general_ci    | 1      |
| keybcs2  | DOS Kamenicky Czech-Slovak  | keybcs2_general_ci  | 1      |
| macce    | Mac Central European        | macce_general_ci    | 1      |
| macroman | Mac West European           | macroman_general_ci | 1      |
| cp852    | DOS Central European        | cp852_general_ci    | 1      |
| latin7   | ISO 8859-13 Baltic          | latin7_general_ci   | 1      |
| cp1251   | Windows Cyrillic            | cp1251_general_ci   | 1      |
| cp1256   | Windows Arabic              | cp1256_general_ci   | 1      |
| cp1257   | Windows Baltic              | cp1257_general_ci   | 1      |
| binary   | Binary pseudo charset       | binary              | 1      |
| geostd8  | GEOSTD8 Georgian            | geostd8_general_ci  | 1      |
| cp932    | SJIS for Windows Japanese   | cp932_japanese_ci   | 2      |
| eucjpms  | UJIS for Windows Japanese   | eucjpms_japanese_ci | 3      |
+----------+-----------------------------+---------------------+--------+
36 rows in set (0.02 sec)

更多mysql的字符集知识可以参考本论坛的
http://www.phpfans.net/bbs/viewt ... &extra=page%3D1
或者mysql官方的
http://dev.mysql.com/doc/refman/5.1/zh/charset.html

MySQL 4.1的字符集支持(Character Set Support)有两个方面:字符集(Character set)和排序方式(Collation)。对于字符集的支持细化到四个层次: 服务器(server),数据库(database),数据表(table)和连接(connection)。
查看系统的字符集和排序方式的设定可以通过下面的两条命令:

mysql> SHOW VARIABLES LIKE 'character_set_%';
+--------------------------+-------------------------------------------+
| Variable_name            | Value                                     |
+--------------------------+-------------------------------------------+
| character_set_client     | latin1                                    |
| character_set_connection | latin1                                    |
| character_set_database   | latin1                                    |
| character_set_filesystem | binary                                    |
| character_set_results    | latin1                                    |
| character_set_server     | latin1                                    |
| character_set_system     | utf8                                      |
| character_sets_dir       | D:\MySQL\MySQL Server 5.0\share\charsets\ |
+--------------------------+-------------------------------------------+
8 rows in set (0.06 sec)

mysql> SHOW VARIABLES LIKE 'collation_%';
+----------------------+-------------------+
| Variable_name        | Value             |
+----------------------+-------------------+
| collation_connection | latin1_swedish_ci |
| collation_database   | latin1_swedish_ci |
| collation_server     | latin1_swedish_ci |
+----------------------+-------------------+
3 rows in set (0.02 sec)

上面列出的值就是系统的默认值。latin1默认校对规则是latin1_swedish_ci,默认是latin1的瑞典语排序方式.
为什么呢默认会是latin1_swedish_ci呢,追溯一下mysql历史很容易发现

1979年,一家瑞典公司Tcx欲开发一个快速的多线程、多用户数据库系统。Tcx 公司起初想利用mSQL和他们自己的快速低级例程 (Indexed Sequential Access Method,ISAM)去连接数据库表,然而,在一些测试以后得出结论:mSQL对其需求来说不够快速和灵活。这就产生了一个连接器数据库的新SQL接口,它使用几乎和mSQL一样的API接口。这个API被设计成可以使那些由mSQL而写的第三方代码更容易地移植到MySQL。

相信如果mysql是中国开发的,那么汉语也是默认编码了

当然我们也可以自己需要修改mysql的默认字符集
在mysql配置文档my.ini,找到如下两句:

[mysql]

default-character-set=latin1



# created and no character set is defined
default-character-set=latin1

修改后面的值就可以。

这里不建议改,仍保留默认值
也就是说启动 mysql时,如果没指定指定一个默认的的字符集,这个值继承自配置文件中的;
此时 character_set_server 被设定为这个默认的字符集; 当创建一个新的数据库时,
除非明确指定,这个数据库的字符集被缺省设定为 character_set_server; 当选定了一个数据库时,
character_set_database 被设定为这个数据库默认的字符集; 在这个数据库里创建一张表时,
表默认的字符集被设定为 character_set_database,也就是这个数据库默认的字符集;
当在表内设置一栏时,除非明确指定,否则此栏缺省的字符集就是表默认的字符集。

这样问题就随之而来了,假如一数据库是gbk编码。如果访问数据库时没指定其的字符集是gbk。
那么这个值将继承系统的latin1,这样就做成mysql中文乱码。

乱码解决方法

要解决乱码问题,首先必须弄清楚自己数据库用什么编码。如果没有指明,将是默认的latin1。
我们用得最多的应该是这3种字符集 gb2312,gbk,utf8。

那么我们如何去指定数据库的字符集呢?下面也gbk为例

【在MySQL Command Line Client创建数据库 】

mysql> CREATE TABLE `mysqlcode` (
    -> `id` TINYINT( 255 ) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY ,
    -> `content` VARCHAR( 255 ) NOT NULL
    -> ) TYPE = MYISAM CHARACTER SET gbk COLLATE gbk_chinese_ci;
Query OK, 0 rows affected, 1 warning (0.03 sec)

mysql> desc mysqlcode;
+---------+-----------------------+------+-----+---------+----------------+
| Field   | Type                  | Null | Key | Default | Extra          |
+---------+-----------------------+------+-----+---------+----------------+
| id      | tinyint(255) unsigned | NO   | PRI |         | auto_increment |
| content | varchar(255)          | NO   |     |         |                |
+---------+-----------------------+------+-----+---------+----------------+
2 rows in set (0.02 sec)

其中后面的TYPE = MYISAM CHARACTER SET gbk COLLATE gbk_chinese_ci;
就是指定数据库的字符集,COLLATE (校勘),让mysql同时支持多种编码的数据库。

当然我们也可以通过如下指令修改数据库的字符集
alter database da_name default character set 'charset'.
php爱好者站 http://www.phpfans.net

客户端以 gbk格式发送 ,可以采用下述配置:

SET character_set_client='gbk'
SET character_set_connection='gbk'
SET character_set_results='gbk'

这个配置就等价于 SET NAMES 'gbk'。

现在对刚才创建的数据库操作

mysql> use test;
Database changed

mysql> insert into mysqlcode values(null,'php爱好者');
ERROR 1406 (22001): Data too long for column 'content' at row 1

没有指定字符集为gbk,插入时出错

mysql> set names 'gbk';
Query OK, 0 rows affected (0.02 sec)

指定字符集为 gbk

mysql> insert into mysqlcode values(null,'php爱好者');
Query OK, 1 row affected (0.00 sec)

插入成功

mysql> select * from mysqlcode;
+----+-----------+
| id | content   |
+----+-----------+
| 1  | php爱好着 |
+----+-----------+
1 row in set (0.00 sec)

在没有指定字符集gbk时读取也会出现乱码,如下

mysql> select * from mysqlcode;
+----+---------+
| id | content |
+----+---------+
| 1  | php???  |
+----+---------+
1 row in set (0.00 sec)


【在phpmyadmin创建数据库,并指定字符集】



表类型根据自己需要选,这里选MyISAM(非事务);
整理选择 gbk_chinese_ci 也就是gbk字符集
gbk_bin 简体中文, 二进制。gbk_chinese_ci 简体中文, 不区分大小写。

在刚才创建的数据库插入数据库



再浏览时发现是乱码


为什么呢?是因为数据库为gbk字符集,而我们操作时没有指定为gbk
回到数据库首页


可以看到 mysql 连接校对默认的latin1_bin。我们将其改为gbk_chinese_ci


再插入一条数据。看,这条已经正常了


更多phpmyadmin乱码问题请参考本论坛的
http://www.phpfans.net/bbs/viewt ... &extra=page%3D1
php爱好者站 http://www.phpfans.net

【解决php读取数据库乱码】

仍以数据库mysqlcode为例

[复制到剪切板]
CODE:
<?php
//php爱好者站教程 http://www.phpfans.net 
$conn mysql_connect("localhost","root","");
mysql_query("set names 'gbk'");//这就是指定数据库字符集,一般放在连接数据库后面就系了
mysql_select_db("test");

$sql "select * from mysqlcode";
$result mysql_query($sql,$conn);

?>
<
head>
<
meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
<
title>mysql 字符编码</title>
</
head>

<
body>
<
table width="300" height="32" border="1" align="center" cellpadding="0" cellspacing="0"
  <
tr>
    <
td width="71" align="center">id</td>
    <
td width="229" align="center">内容</td>
  </
tr>
 <?
php while($row mysql_fetch_assoc($result)){
 echo 
"  
 <tr>
    <td align=\"center\">"
.$row['id']."</td>
    <td>"
.$row['content']."</td>
  </tr>"
;
}?>  
</
table>
</
body>
</
html>
<?
php mysql_free_result($result);?> ;

如果我们将mysql_query("set names 'gbk'");注释掉,肯定时乱码


加上那句又正常了


注意: set names 必须在连接数据库之后,执行sql语句之前!
一句话
你数据库用什么编码,在对数据库操作之前就set names '你的编码';

终于完了,如果对大家有用就顶下啦。不正确的地方也请指正
php爱好者站 http://www.phpfans.net

ps:页面申明编码:在HTML代码HEAD里面,可以用<meta http-equiv="Content-Type" content="text/html; charset="XXX" />来告诉浏览器网页采用了什么编码,目前中文网站开发中主要用的是GB2312和UTF-8两种编码。
作者: teddymicro    时间: 2006-9-1 05:23

这个不错,我以前就是用LATIN1的,用一些东西会有乱码,现在转成GBK的就好了.
作者: 彩色沙漠    时间: 2006-10-17 08:41

好好学习中~~看到上面的我的问题解决了~~呵呵
作者: shamofengbao    时间: 2006-10-25 09:18

我的问题也解决了.十分感谢啊!!!
作者: jason.lee    时间: 2006-11-30 16:00     标题: insert数据后,就出现乱码,该怎么办?

mysql> SHOW VARIABLES LIKE 'character_set_%';
+--------------------------+----------------------------------+
| Variable_name            | Value                            |
+--------------------------+----------------------------------+
| character_set_client     | gbk                              |
| character_set_connection | gbk                              |
| character_set_database   | utf8                             |
| character_set_results    | gbk                              |
| character_set_server     | utf8                             |
| character_set_system     | utf8                             |
| character_sets_dir       | /usr/local/share/mysql/charsets/ |
+--------------------------+----------------------------------+
7 rows in set (0.00 sec)

mysql>  SHOW VARIABLES LIKE 'collation_%';
+----------------------+-----------------+
| Variable_name        | Value           |
+----------------------+-----------------+
| collation_connection | gbk_chinese_ci  |
| collation_database   | utf8_general_ci |
| collation_server     | utf8_general_ci |
+----------------------+-----------------+


我的字符集为这样,但insert数据后,就出现乱码,该怎么办?
作者: 心若水寒    时间: 2006-11-30 16:34

该认真看下这篇文章
作者: 蓝雨    时间: 2006-11-30 23:44     标题: 拉feel


作者: hacky_hui    时间: 2006-12-24 12:05

现在还有个问题,就是从PHP文件中往数据库里面写资料也出现乱码的情况怎么办呢?
作者: 巴乔    时间: 2006-12-25 10:22

引用:
原帖由 hacky_hui 于 2006-12-24 12:05 发表
现在还有个问题,就是从PHP文件中往数据库里面写资料也出现乱码的情况怎么办呢?
应该再认真看看这篇文章.看看问题到底出在哪里
作者: zizhilianqiu    时间: 2007-1-21 18:04

我还是解决不了?我用的3合1的软件.按上面说道.往数据库里写都写不进去.如果要是数字字母可以.不知道为什么.那个高手指点一下呀?小弟感激不尽.
作者: zizhilianqiu    时间: 2007-1-21 18:11

谢谢哥哥们.我的问题也解决了,忽忽.
作者: 纯色理想    时间: 2007-3-4 19:59

嗯 这个确实是初学者最头疼的问题
作者: zdyzzj    时间: 2007-5-4 16:16


作者: fly_yang    时间: 2007-5-9 17:28

谢谢了`我的中文解决了`非常感谢
作者: 木鱼精    时间: 2007-5-9 17:33

看了。。。。头晕晕的。。。
作者: gmlee1999    时间: 2007-5-27 12:58

好东西,顶下,学习........thx
作者: 04net    时间: 2007-5-29 17:58

斑竹,在phpmyadmin中的mysql连接校对怎么改不了,恳请帮个帮.  还有表单提交成功但是在数据库当中只显示ID号和时间,其它的怎么插不进去呢?这个是什么问题呢
作者: 心若水寒    时间: 2007-5-29 18:20     标题: 回复 #17 04net 的帖子

高版本的phpmydamin默认是utf8的.我用的版本是2.7
作者: 04net    时间: 2007-5-29 19:56

我用的是phpMyAdmin-2.10.0.2-all-languages.zip版本的,那在phpmyadmin中的mysql连接校对怎么改不了?恳请帮助,谢谢斑竹
作者: 心若水寒    时间: 2007-5-29 20:07     标题: 回复 #19 04net 的帖子

我也不知道
作者: 奇将射天狼    时间: 2007-7-26 11:11

引用:
原帖由 hacky_hui 于 2006-12-24 12:05 发表
现在还有个问题,就是从PHP文件中往数据库里面写资料也出现乱码的情况怎么办呢?
你这种情况,可以在写入数据库的时候添加这个语句
mysql_query("set names 'gbk'");
或者:mysql_query("set names 'utf8'");  
同时,读取的时候也要加入这个语句就可以了。
作者: dwrobin    时间: 2007-9-5 10:26

我昨天为这问题忙活了半天,谢谢LZ啊
作者: 独自迷茫    时间: 2007-9-24 17:01

还是很迷茫  不过慢慢看把
作者: fox0296    时间: 2007-9-27 14:20

引用:
原帖由 04net 于 2007-5-29 19:56 发表
我用的是phpMyAdmin-2.10.0.2-all-languages.zip版本的,那在phpmyadmin中的mysql连接校对怎么改不了?恳请帮助,谢谢斑竹
我用的也是这个版本
现在也无法修改连接校对字符集 ,不管修改时选什么,屏幕闪一下又自动变成 utf8_general_ci 了
我是按着本论坛的帖子一步一步配置的.
希望高人能给解决下这个问题~~~
作者: ylqfp    时间: 2007-10-3 19:25

谢谢,这两天都快给乱码搞死了
作者: MrBool    时间: 2007-10-11 13:04

好!!
作者: suger_cgq    时间: 2007-10-23 17:43     标题: 这篇文章的好

这篇文章写的最详细,我弄了六七个小时,在网上查了很多资料,看了这篇文章才搞定,哎.....
谢谢...

[ 本帖最后由 suger_cgq 于 2007-10-23 17:44 编辑 ]
作者: zhjy002    时间: 2007-11-21 10:02     标题: 真是辛苦了

支持下下
作者: applejuzi    时间: 2007-11-21 11:14

感谢版主的无私奉献
作者: aabb00    时间: 2007-12-24 12:53

路见好贴一个项!

用最新版本phpmyadmin和mysql就不必这样麻烦了,只需设置mysql默认编码即可,都是软件惹的祸。

[ 本帖最后由 aabb00 于 2007-12-24 13:46 编辑 ]
作者: lige070928    时间: 2007-12-28 18:40

好东西学习了
作者: guaishi    时间: 2008-2-4 17:16

搞不明白的问题让楼主给点通了
作者: d_bsky    时间: 2008-2-28 19:32

等我出现问题我再慢满研究.哈哈
作者: zhenjie    时间: 2008-3-3 15:53     标题: 有点启发

看了这篇文章,是不是可以这样理解,数据库的连接校对码是GBK,在PHP中加上 set names 'GBK;再读取或写入数据就不会出现中文乱码
作者: liulp15    时间: 2008-10-9 16:37

好详细!看到了就支持一下,暂时还没有碰到这个问题。先谢谢啦!:)
作者: wangvmeng    时间: 2008-11-6 20:25

支持下 代表自己感谢下楼主的辛苦
作者: 鸡鸡    时间: 2008-11-11 04:38

lz嫁给我吧..........

我通宵达旦几天搞不好的问题.看了你的文章就解决了.

专门注册感谢的
作者: oshine    时间: 2008-12-5 20:14

学习了,感谢分享..
作者: jpke    时间: 2008-12-30 19:23

谢谢 了哦 感觉很详细
作者: maozhihui77    时间: 2009-4-30 13:53

最便宜的空间出售了..价格99元.需要的联系QQ:1131170296
作者: 飘云    时间: 2009-8-1 16:58

学习到了
作者: bluesjim    时间: 2009-8-18 10:29     标题: 照你的操作创建mysqlcode数据库最后错误,提示没有选择数据库:No database selected

请楼主帮忙解决一下这个的问题,我的phpadmin的版本号是:phpMyAdmin v2.8.0.2
作者: maieve    时间: 2009-10-3 11:19

good
作者: kahn178    时间: 2009-10-9 11:47

好東西,學習了。。。。。。。。。。。。。。。。。。
作者: 302875931    时间: 2009-10-22 11:02

真钱游戏
温州棋牌
乐清棋牌
真钱棋牌
真钱棋牌
作者: stiffany    时间: 2009-11-30 21:46

稍后学习
作者: haizeng    时间: 2009-12-4 11:28

恩 学习啦
作者: nyyxchen    时间: 2010-4-20 16:19

太想学习php,十分感谢。
作者: gzlove    时间: 2010-7-22 22:24

过业看看。。。
作者: wangkenv    时间: 2011-11-10 17:53

设置成gb2312
作者: wwwlv567com    时间: 2012-1-12 15:34

。。。。。。。
作者: php0731    时间: 2012-7-5 10:09     标题: 长沙源码PHP培训——PHP程序员,LAMP工程师

湖南长沙源码培训——湖南最专业的PHP、LAMP培训机构及实训基地,我们拥有一支经验丰富的讲师团队,核心讲师具有多年互联网开发经验及教学经验,打造湖南最专业的PHP培训机构。走高薪就业捷径,毕业后无须实习,直接上岗就业,签订就业协议。

实训环境——针对企业办公模式,人手一台笔记本,饮水机,空调,会议室圆桌式讲学,自由,开放,自律的学习环境,早日培养学员职业综合素质。

课程介绍——从零基础课程开始,包括HTML,CSS+DIV,PHP,MySQL,JavaScript,Ajax,XML,项目管理,PHP服务器搭建,面向对象思想,MySQL高级应用,开源产品模板技术,网络安全,系统优化,邮件服务,数据采集系统,ZendStudio,Eclipse等开发工具,Zend产品应用,掌握大中型网站技术解决方案,使用控制系统SVN管理文件版本,掌握高效、快速、协作的项目流程,独立完成或团队合作开发4个以上项目。安排系列就业指导课程,安排模拟面试。

联系方式:
固话:0731-82259438
QQ: 1181280679
网址:http://www.php0731.com
地址:长沙市五一东路附2号晓园大厦7楼(长沙火车站正对面)
作者: dahuilang123123    时间: 2012-9-17 18:42     标题: 谢谢大家的分享

糖尿病专家在线答疑
作者: wltusu    时间: 2012-12-27 15:39

收藏了。。
作者: hotelcn2007    时间: 2013-1-3 15:25

我还是解决不了?我用的3合1的软件.按上面说道.往数据库里写都写不进去.如果要是数字字母可以.不知道为什么.那个高手指点一下呀?小弟感激不尽.
作者: 廉宇轩    时间: 2013-1-11 11:16     标题: 想学习更多

选择千锋 选择卓越  千锋3G 手机软件开发培训第一品牌

android培训 北京android培训  android开发
作者: tcf120    时间: 2013-3-20 11:39

mysql字符编码是版本4.1引入的,支持多国语言,而且一些特性已经超过了其他的数据库系统。
作者: 可可可    时间: 2013-8-13 13:07


作者: 娇娇1234    时间: 2013-9-16 10:28

向楼主学习
作者: 大环乙木    时间: 2014-6-4 15:17

好强大的代码




欢迎光临 PHP爱好者论坛 (http://www.phpfans.net/bbs/) Powered by Discuz! 6.1.0