MySQL中文乱码问题的解决第1/2页

2022-11-12 09:19:13
内容摘要
这篇文章主要为大家详细介绍了MySQL中文乱码问题的解决第1/2页,具有一定的参考价值,可以用来参考一下。 对此感兴趣的朋友,看看idc笔记做的技术笔记!转自:http://www.phpchina.c
文章正文

这篇文章主要为大家详细介绍了MySQL中文乱码问题的解决第1/2页,具有一定的参考价值,可以用来参考一下。

对此感兴趣的朋友,看看idc笔记做的技术笔记!

转自:http://www.phpchina.cn/viewarticle.php?id=1584下面要写的是一篇非常无聊的东西,充斥了大量各式各样的编码、转换、客户端、服务器端、连接……呃,我自己都不愿意去看它,但想一想,写下来还是有点意义的,原因有四:MySQL 4.1 对多语言的支持有了很大变化 (这导致了问题的出现);尽管大部分的地方 (包括个人使用和主机提供商),MySQL 3 仍然占主导地位;但 MySQL 4.1 是 MySQL 官方推荐的数据库,已经有主机提供商开始提供并将会越来越多;许多 PHP 程序以 MySQL 作为默认的数据库管理软件,但它们一般不区分 MySQL 4.1 与 4.1 以下版本的区别,笼统地称“MySQL 3.xx.xx 以上版本”就满足安装需求了;因为 latin1 在许多地方 (下边会详细描述具体是哪些地方) 作为默认的字符集,成功的蒙蔽了许多 PHP 程序的开发者和用户,掩盖了在中文等语言环境下会出现的问题;简单的说,MySQL 自身的变化和使用 MySQL 的 PHP 程序对此忽略,导致了问题的出现和复杂化,而由于大部分用户使用的是英文,使这种问题不被重视。这里提到的 PHP 程序,主要就 WordPress 而言。MySQL 4.1 字符集支持的原理MySQL 4.1 对于字符集的指定可以细化到一台机器上安装的 MySQL,其中的一个数据库,其中的一张表,其中的一栏,应该用什么字符集。但是,传统的 Web 程序在创建数据库和数据表时并没有使用那么复杂的配置,它们用的是默认的配置,那么,默认的配置从何而来呢?编译 MySQL 时,指定了一个默认的字符集,这个字符集是 latin1;安装 MySQL 时,可以在配置文件 (my.ini) 中指定一个默认的的字符集,如果没指定,这个值继承自编译时指定的;启动 mysqld 时,可以在命令行参数中指定一个默认的的字符集,如果没指定,这个值继承自配置文件中的;此时 character_set_server 被设定为这个默认的字符集;当创建一个新的数据库时,除非明确指定,这个数据库的字符集被缺省设定为 character_set_server;当选定了一个数据库时,character_set_database 被设定为这个数据库默认的字符集;在这个数据库里创建一张表时,表默认的字符集被设定为 character_set_database,也就是这个数据库默认的字符集;当在表内设置一栏时,除非明确指定,否则此栏缺省的字符集就是表默认的字符集;这个字符集就是数据库中实际存储数据采用的字符集,mysqldump 出来的内容就是这个字符集下的; 简单的总结一下,如果什么地方都不修改,那么所有的数据库的所有表的所有栏位的都用 latin1 存储,不过我们如果安装 MySQL,一般都会选择多语言支持,也就是说,安装程序会自动在配置文件中把 default_character_set 设置为 UTF-8,这保证了缺省情况下,所有的数据库的所有表的所有栏位的都用 UTF-8 存储。当一个 PHP 程序与 MySQL 建立连接后,这个程序发送给 MySQL 的数据采用的是什么字符集?MySQL 无从得知 (它最多只能猜测),所以 MySQL 4.1 要求客户端必须指定这个字符集,也就是 character_set_client,MySQL 的怪异之处在于,得到的这个字符集并不立即转换为存储在数据库中的那个字符集,而是先转换为 character_set_connection 变量指定的一个字符集;这个 connection 层究竟有什么用我不大明白,但转换为 character_set_connection 的这个字符集之后,还要转换为数据库默认的字符集,也就是说要经过两次转换;当这个数据被输出时,又要由数据库默认的字符集转换为 character_set_results 指定的字符集。一个典型的环境典型的环境以我自己的电脑上安装的 MySQL 4.1 为例,我自己的电脑上安装着 Apache 2,PHP 5 和 WordPress 1.5.1.3,MySQL 配置文件中指定了 default_character_set 为 utf8。于是问题出现了:WordPress 按照默认情况安装,所以所有的表都用 UTF-8 存储数据;WordPress 默认采用的浏览字符集是 UTF-8 (Options->Reading 中设置),因此所有 WP 页面的 meta 中会说明 charset 是 utf-8;所以浏览器会以 utf-8 方式显示所有的 WP 页面;这样一来 Write 的所有 Post,和 Comment 都会以 UTF-8 格式从浏览器发送给 Apache,再由 Apache 交给 PHP;所以 WP 从所有的表单中得到的数据都是 utf-8 编码的;WP 不加转换的直接把这些数据发送给 MySQL;MySQL 默认设置的 character_set_client 和 character_set_connection 都是 latin1,此时怪异的事情发生了,实际上是 utf-8 格式的数据,被“当作 latin1”转换成……居然还是转换成 latin1,然后再由这个 latin1 转换成 utf-8,这么两次转换,有一部分 utf-8 的字符就丢失了,变成 ??,最后输出的时候 character_set_results 默认是 latin1,也就输出为奇怪的东西了。最神奇的还不是这个,如果 WordPress 中设置以 GB2312 格式阅读,那么 WP 发送给 MySQL 的 GB2312 编码的数据,被“当作 latin1”转换后,存进数据库的是一种奇怪的格式 (真的是奇怪的格式,mysqldump 出来就能发现,无论当作 utf-8 还是当作 gb2312 来读都是乱码),但如果这种格式以 latin1 输出出来,居然又能变回 GB2312!这会导致什么现象呢?WP 如果使用 MySQL 4.1 数据库,把编码改用 GB2312 就正常了,可惜,这种正常只是貌似正常。如何解决问题如果你已经不耐烦了 (几乎是肯定的),google 一下,会发现绝大部分的解答是,query 之前先执行一下:SET NAMES 'utf8',没错,这是解决方案,但本文的目的是说明,这为什么是解决方案。要保证结果正确,必须保证数据表采用的格式是正确的,也就是说,至少能够存放所有的汉字,那么我们只有两种选择,gbk 或者 utf-8,下面讨论 utf-8 的情况。因为配置文件设置的 default_character_set 是 utf8,数据表默认采用的就是 utf-8 建立的。这也应该是所有采用 MySQL 4.1 的主机提供商应该采用的配置。所以我们要保证的只是客户端与 MySQL 交互之间指定编码的正确。这只有两种可能,客户端以 gb2312 格式发送数据,或者以 utf-8 格式发送数据。如果以 gb2312 格式发送:SET character_set_client='gb2312'SET character_set_connection='utf8' 或者SET character_set_connection='gb2312'都是可以的,都能够保证数据在编码转换中不出现丢失,也就是保证存储入数据库的是正确的内容。怎么保证取出的是正确的内容呢?考虑到绝大部分客户端 (包括 WP),发送数据的编码也就是它所希望收到数据的编码,所以:SET character_set_results='gb2312'可以保证取出给浏览器显示的格式就是 gb2312。如果是第二种情况,客户端以 utf-8 格式发送 (WP 的默认情况),可以采用下述配置:SET character_set_client='utf8'SET character_set_connection='utf8'SET character_set_results='utf8'这个配置就等价于 SET NAMES 'utf8'。WP 应该作什么修改还是那句话,客户端要发给数据库什么编码的数据,数据库是不可能确切知道的,只能让客户端自己说明白,所以,WP 是必须发送正确的 SET... 给 MySQL 的。怎么发送最合适呢?台湾的 pLog 同仁给出了一些建议:首先,测试服务器是否 >= 4.1,编译时是否加入了 UTF-8 支持;是则继续然后测试数据库以什么格式存储 ($dbEncoding);SET NAMES $dbEncoding对于第二点,WP 的情况是不同的,按照上面的典型配置,只要用 WP,肯定数据库是用 UTF-8 存储的,所以要根据用户设置的以 GB2312 还是 UTF-8 浏览来判断 (bloginfo('charset')),但这个值是要连接数据库以后才能得到的,所以效率最高的方式是连接数据库之后,根据这个配置设置一次 SET NAMES,而不必每次查询之前都设置一遍。我的修改方式是这样的,在 wp_includes/wp-db.php 中增加:function set_charset($charset){// check mysql version first.$serverVersion = mysql_get_server_info($this->dbh);$version = explode('.', $serverVersion);if ($version[0] < 4) return;// check if utf8 support was compiled in$result = mysql_query("SHOW CHARACTER SET like 'utf8'",$this->dbh);if (mysql_num_rows($result) < = 0) return;if ($charset == 'utf-8' || $charset == 'UTF-8')$charset = 'utf8';@mysql_query("SET NAMES '$charset'", $this->dbh);}在 wp-settings.php 的 require (ABSPATH . WPINC . '/vars.php'); 后增加:$wpdb->set_charset(get_bloginfo('charset'));http://www.phpchina.cn/viewarticle.php?id=1584
12下一页阅读全文

对此感兴趣的朋友,看看idc笔记做的技术笔记!

1. MySQL 4.1 在文字上有很大改进,它有了 Character Set 与 Collation 的慨念。2. 在 MySQL 4.0 ,一般的程式都会将文字以拉丁文 ( latin) 来储存,就算我们输入中文字,结果仍是放在以拉丁文设置的文字栏里头,这对 MySQL 4.0 与以 MySQL 4.0 为基楚的程式来说,并不会有问题。3. 可是 MySQL 4.1 的系统编码是预设用 UTF-8 的,当要 restore MySQL 4.0 的 backup 档到 MySQL 4.1 时,乱码就出现了。原因在于 MySQL 4.1 将 latin 码转换过来,而后转换是并不完全完美的,这导致了出现少量文字出现乱码现象。4. 要解决这乱码问题并不难。首先,在 MySQL 4.0 备份时,先将所有文字栏变成 binary 类型,然后进行正常备份。第二步,可在 MySQL 4.1 里将刚才的备份 restore。最后,将较早前所变更到 binay 类型的文字栏,再次复原到文字类型。这样中文编码的问题就应该可以完全解决。5. 将文字栏变更到 binay 类型时,必需设定 binary 栏的长度大过或等于 (>=) 文字栏的长度,否则资料会失去。6. 另外,经这样升级的 MySQL 数据库,在 MySQL 4.1 里将会正常工作,就算是怎样 backup 与 restore 都不会再有乱码问题。作者: MySQL 发布日期: 2005-12-14mysql4.1是比较烦人,支持多语言的细化设置,再加上phpmyadmin2.6也比较笨,默认就是改不动的utf8,怎么弄都乱码。好了,废话少说,我们来一步步解决这个问题:1.修改/etc/my.cnf文件,改成这样:[mysqld]datadir=/var/lib/mysqlsocket=/var/lib/mysql/mysql.sockdefault-character-set=utf8[mysql.server]user=mysqlbasedir=/var/lib[mysqld_safe]err-log=/var/log/mysqld.logpid-file=/var/run/mysqld/mysqld.pid注意:就是加入了一句default-character-set=utf8。2./etc/init.d/mysqld restart 重新启动mysql;3.打开phpmyadmin,选择lang为"Chines simplifies(zh-utf-8)",选择"MySQL 连接校对"为"utf8_general_ci "点“显示 MySQL 的运行信息”--“变量”,可以看到:character set client utf8 utf8character set connection utf8 utf8character set database utf8 utf8character set results utf8 utf8character set server utf8 utf8character set system utf8 utf8collation connection utf8_general_ci utf8_general_cicollation database utf8_general_ci utf8_general_cicollation server utf8_general_ci utf8_general_ci从这里可以看到character全部变成utf8了。有人要问,为什么都要改成utf8呢?改成GB2312不行吗?解释如下:我也不想改成utf8,只是phpmyadmin2.6在mysql4.1的时候只会用utf8,连其他页面的charset也都是utf8,改成gb2312一定会乱码,我们只能凑phpmyadmin了。只有在mysql3.23的时候,phpmyadmin才会多一个gb2312的页面charset,这时候是正常的。3.将以前的mysql3的库文件导入mysql4.1的库有两种情况:一是从phpmyadmin上导入,这时候你要注意的是在选择库文件的页面左下脚有个“文件的字符集:”,默认是utf8,要改成gb2312,否则导进去乱码;二是在linux下导入,这时候你需要先在库文件的头部加一行:SET NAMES 'gb2312'; 注意最后也是;号,别漏了。然后执行mysql -u用户名 -p密码 xxx.sql > 库名导入完成以后再用phpmyadmin打开看,里面的中文字就是正确的。4.从mysql4.1里导出库文件一.用phpmyadmin导出导出倒是问题不大,如果phpmyadmin的浏览页面里显示的中文是正常的,那么导出肯定也是正常的二.在linux上导出如果用mysqldump导出出现了乱码也没有关系,可以运行iconv来转换一下iconv -c -f UTF-8 -t GB2312 库文件名 > 新的gb2312的库文件名综上所述,你要注意:1。尽量在需要导入的库文件的开头加入SET NAMES 'gb2312';告诉mysql你要导入的是一个gb2312的文件;2。可能你需要这个:SET NAMES 'utf8';在登陆到mysql后用,把character的一些默认参数改到utf8上,有时可以减少一些困扰,不过也不是必须的。在mysql上使用:SHOW VARIABLES LIKE 'character_set_%';用来查看当前的状态。3.如果出现乱码也不要怕,一是你要注意留存原有的备份,二是用iconv来进行转化。在正常使用之前注意做导入导出的测试,确保万无一失。最后加一句:www.quicklinux.org原创文章,转载请注明出处。呵呵邮件:support@quicklinux.org作者: MySQL 发布日期: 2005-12-14我升级了MYSQL到4.1.2,phpmyadmin用的是2.6.2。数据表里面有中文的字段中文都变成了乱码,导出数据也是乱码。我用以前的2.5.7没有问题,想问一下,应该在phpmyadmin的那个文件里改哪个设置一下才能显示出来的是正常的中文字?和字符相关的变量中这几个和sql很有关系:character_set_clientcharacter_set_connectioncharacter_set_results此外就是数据库中对相应字段设置的charact set,如果没有对字段设置,缺省是table的charact set,table也没有指定则缺省使用database的。上面3个变量的作用是这样的,client表示客户端发送过来的字符集,results表示发送到客户端的字符集(这两个分开是因为发送过来和发送过去的不一定是同一个客户端),connection则在客户端和数据库起一个连接作用。具体是这样:比如我在mysql命令行设置client为gbk,connection为utf8,results为gbk,数据库为big5,当我发送一个insert语句的时候,这个语句作为gbk代码,先转为utf8代码(connection),再转为big5(database)插入数据库。而运行一个select语句的时候,从数据库得到的结果则相反的过程,由big5转为utf8,再转为gbk,你得到gbk的结果。因此最主要的是让client和results和你使用的客户端一致。比如你的网页是utf8编码,你就要设置这两个为utf8。而在mysql命令行的时候,我用的是2000,需要设置为gbk而我们用的set names XXX,实际上就是同时设置这3个变量为XXX。在这样的情况下,我们可以把一个数据库中的不同表或不同字段设为不同的字符集,只要上面3个设置正确,就可以在数据库中同时使用不同的字符集。注意要保证你的数据库中的字符已经使用了正确的字符集,比如如果一开始你设置错误,插入数据后,本身数据的编码就是不正确的,然后即使设置改回来,也不可能得到正确的显示了。还有一个是编码互相之间的兼容性,如果一个字符在gbk中有,在utf8中没有,那么在gbk-》utf8-》gbk的过程中,它就变成了“?”再说一下具体解决的办法。首先要指定你的升级后的database及table及field的character set,一般来说我们用gb2312或者utf8的,如果不同时使用多种编码,只要指定database就可以,可以在建库的sql语句加上相应的character set,在phpMyAdmin里也可以修改。然后是导入旧数据。首先要确定自己的数据文件的编码。如果用phpMyAdmin导入,在界面上有文件编码的选项,一定要和数据文件的编码一致。如果从mysql的命令行导入,就要自己设置上面说到的3个变量,set names xxx。使用其它的客户端程序一样要注意。这样就可以让旧数据转入新数据库后的编码才是正确的,如果这一步错了,后面不可能得到正确的显示。然后是自己的程序,在连接后就可以执行一次set names xxx,根据你的网页编码而定。这样基本就可以保证编码正确了。你很有可能是导入的数据编码已经不对了。转自:http://www.zhaodaola.org/blog/p/mysql-luanma.phpMYSQL数据库默认语言为瑞典语, 现有一GB2312字符的数据库.结构OK. 为什么内容是乱码? 不重装数据库有办法解决码?从MySQL 4.1开始引入的多语言支持确实很棒,而且一些特性已经超过了其他的数据库系统。不过我在测试过程中发现使用适用于MySQL 4.1之前的PHP语句操作MySQL数据库会造成乱码,即使是设置过了表字符集也是如此。我读了一下新的MySQL在线手册中第十章"Character Set Support"后终于找到了解决方法并测试通过。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_results | latin1 || character_set_server | latin1 || character_set_system | utf8 || character_sets_dir | /usr/share/mysql/charsets/ |+--------------------------+----------------------------+7 rows in set (0.00 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.00 sec)上面列出的值就是系统的默认值。(很奇怪系统怎么默认是latin1的瑞典语排序方式)...当我们按照原来的方式通过PHP存取MySQL数据库时,就算设置了表的默认字符集为utf8并且通过UTF-8编码发送查询,你会发现存入数据库的仍然是乱码。问题就出在这个connection连接层上。解决方法是在发送查询前执行一下下面这句:SET NAMES 'utf8';它相当于下面的三句指令:SET character_set_client = utf8;SET character_set_results = utf8;SET character_set_connection = utf8;再试试看,正常了吧?^_^ Enjoy!具体讲在你的查询前加一行:mysql_query("SET NAMES 'gb2312';",$this->con);真应该把手册仔细看一遍.
上一页12阅读全文

注:关于MySQL中文乱码问题的解决第1/2页的内容就先介绍到这里,更多相关文章的可以留意

代码注释

作者:喵哥笔记

IDC笔记

学的不仅是技术,更是梦想!