php和mysql乱码

 

最近刚刚才接触wamp 遇到乱码问题。费了好大的气力才解决!问题分析,希望对大家有用

php和mysql涉及到的字符有php前端页面字符集,mysql数据库字符集,和连接字符集。

1.php前端页面字符集。

   php文件中的html脚本字符编码通过<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>进行设置,故html使用的编码就是utf8

   另外我们知道每个文件本身都有自己的编码,将文件另存为需要的编码。一般要与页面的html编码一致,故可以将文件编码设置utf8。因为php经常

   要应用js文件,如果js中的文件编码与php文件的编码不一直,那么js文件的中文汉字引用到php文件中会出现乱码。故js文件的编码要与php文件的

   编码和html脚本编码一直。这样浏览器解析的时候不会出现乱码。

2.mysql数据字符集编码。

   Mysql的字符集里有两个概念, 一个是“Character set(字符集)”,另一个是“Collations”(字符序)。

   查看mysql字符集编码通过命令 show variables like '%char%' 以及 show variables like '%coll%' 来分别查看mysql字符集和字符序的编码

   2.1 mysql字符集编码有  

      character_set_server:默认的内部操作字符集

      character_set_client:客户端来源数据使用的字符集

      character_set_connection:连接层字符集

      character_set_results:查询结果字符集

      character_set_database:当前选中数据库的默认字符集

      character_set_system:系统元数据(字段名等)字符集

      mysql默认字符集为latin1,但可以通过在mysql配置文件my.ini中通过在[client]下添加default-character-set = utf8 设置成所需要的编码。

      mysql数据库字符集主要包含几层概念,分别是数据库级别的字符集,数据表的字符集和表中字段的字符集。默认情况下,三个字符集都是从大到小继承的关系。默认字符集是character_set_server的字符集。

    2.2 mysql字符集转换过程

        character_set_client =>character_set_connection=>character_set_results

       例如,想数据表插入utf8的字符,如果采用默认字符集(latin1)。而数据表字段编码为(gbk)。故utf8字符集从在客户端传个mysql服务器,而mysql的character_set_client表示希望得到什么样的字符集,而接受到是utf8,故mysql将其首先转码成latin1的编码,而character_set_connection是latin1,故编码不变。最后将字符存入为gbk的编码,故将latin1的字符集最后有换成gbk。故存入为乱码。

       继续解析:utf8用3个字节表示一个汉字,经过mysql服务器的转换就转换成了3个latin1的字符。因为latin1有一个字节编码。最后存入数据表的时候,又将3个现在是latin1的字符转换成GBK,而GBK是有两个字节进行字符编码,但由于latin1的字符是一个字节表示,故GBK就另外自己加了一个字节来组成两个字节来转换编码,故存入了3个转换后字符,乱码出现。

     读取方式类似插入的逆过程。

3.php和mysql乱码解决

   首先查看mysql数据库的字符集编码,然后设置php连接mysql的字符集方式,尽量两者保持一致。 

   PHP通过设置character_set_client,告诉Mysql,PHP存进数据库的是什么编码方式。

   PHP通过设置character_set_results,告诉Mysql,PHP需要取什么样编码的数据。

   PHP通过设置character_set_connection,告诉Mysql,PHP查询中的文本,使用什么编码。

  那么PHP如何设置呢? 即通过mysql_query(“set names utf8”);如果采用CI框架,则在config下面的database.php里面设置char_set。

 即首先数据建表时采用的是utf8,通过mysql_query来设置php连接mysql的方式,也采用utf8,而且页面html是utf8。则乱码将不会出现。

  但是,事情往往事与愿违,可能我们只是负责页面的设计,而采用别人已经建立好的数据库,就无法保证一致的字符集。

  很多人在建立数据库的时候都采用了默认latin1的字符集,这样里面的中文字段是字符集默认为GBK(这个还不太明白,为什么是GBK)。

   而PHP在制作html页面的时候采用的是通过的utf8编码。 这样查询出来的结果就会是乱码。

   不过没关系,尽管数据库采用的默认字符集,但我们依然要使用mysql_query来进行设置连接字符集与默认字符集保持一直。

   故将其设置为latin1。这样,字符集在经历client , connection, results的时候就保持一值,不会出现转换。例如,数据库都是默认字符集latin1,

  在默认下,中文字段GBK。而连接方式的字符集设置是latin1,故数据表的数据传输就不会发生转换,因为里面的都是latin1的方式传。

  最后在php页面,故接受到的中文就是GBK的中文,而php一般中文字符都采用utf8的编码。

  那么我们只需要将查询出来的结果转换成utf8 即可。

 查询过程:

  如 采用iconv和mb_convert_encoding转换         $result = iconv("gbk","utf8//IGNORE",$result);   iconv第一个参数为源编码,第二个为目标编码
                 $result= mb_convert_encoding( $result,"utf8","gbk");   mb_convert_encoding第二个参数目标编码,第三个为源码。

    尽管mb_convert_encoding的函数效率问题较低,但是它屏蔽了iconv的一些bug。有时候采用iconv转换字符时,会出现Wrong set 不能转换的问题。

  使用mb_convert_encoding可以解决。 如我出现过GBK无法与utf8转换的问题,用mb_convert_encoding解决了。

 插入过程:

           就是将页面输入的utf8的字符转换成GBK的字符,然后执行sql插入。如插入数据库的时候也无乱码。

  两者结合就可以保证查询和插入,修改时,页面和数据库都无乱码。

    关键是保证连接字符集和数据库的字符集保持一直。这样可以保证mysql内部的多种字符集无转换。只要进行数据表字段和页面字符集间的转换即可。

 

笔者是新人,记录下自己的总结。都是文字描述,请谅解!而且自己对字符集的问题,依然有理解上的问题。如果写错了,请包容!~

 

继续努力学习!~~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值