• 关于数据库字符集的问题


    SET NAMES UTF8的具体作用是什么?

    那么,有个问题,如果在DSN中指定了charset, 是否还需要执行set names <charset>呢?

    是的,不能省。set names <charset>其实有两个作用:

    A.  告诉mysql server, 客户端(PHP程序)提交给它的编码是什么

    B.  告诉mysql server, 客户端需要的结果的编码是什么

    也就是说,如果数据表使用gbk字符集,而PHP程序使用UTF-8编码,我们在执行查询前运行set names utf8, 告诉mysql server正确编码即可,无须在程序中编码转换。这样我们以utf-8编码提交查询到mysql server, 得到的结果也会是utf-8编码。省却了程序中的转换编码问题,不要有疑问,这样做不会产生乱码。

    那么在DSN中指定charset的作用是什么? 只是告诉PDO, 本地驱动转义时使用指定的字符集(并不是设定mysql server通信字符集),设置mysql server通信字符集,还得使用set names <charset>指令。

    改变了character_set_client/character_set_connection/character_set_results三个值

    是的,一条命令等于你所列的3条,主要确保编码一致性不乱码

    解决乱码的方法,我们经常使用“set names utf8”,那么为什么加上这句代码就可以解决了呢?下面跟着我一起来深入set names utf8的内部执行原理

    先说MySQL的字符集问题。Windows下可通过修改my.ini内的

    PHP代码

    [mysql

    default-character-set=utf8    //客户端的默认字符集
    [mysqld]

    default-character-set=utf8    //服务器端默认的字符集

    假设我们把两个都设为utf8,然后在MySQL Command Line Client里面输入“show variables like“character_set_%”;”,可看到如下字符:
    character_set_client   latin1
    character_set_connection    latin1
    character_set_database     utf8
    character_set_results    latin1
    character_set_server   utf8
    character_set_system     utf8
    要是我们通过采用UTF-8的PHP程序从数据库里读取数据,很有可能是一串“?????”或者是其他乱码。

    解决办法是,在连接数据库之后,读取数据之前,先执行一项查询“SET NAMES UTF8”,即在php里为

    mysql_query("SET NAMES UTF8");   

    //该句话一定要放在数据库服务器连接语句【$connection=mysql_connect($db_host,$db_user,$db_psw)or die("连接服务器失败");】之后

    即可显示正常(只要数据库里信息的字符正常)。

    到MySQL命令行输入“SET NAMES UTF8;”,然后执行“show variebles like“character_set_%”;”,发现原来为latin1的那些变量“character_set_client”、“character_set_connection”、“character_set_results”的值全部变为utf8了,原来是这3个变量在捣蛋。

    查阅手册,上面那句等于:

    SET character_set_client = utf8;     

    SET character_set_results = utf8;    

    SET character_set_connection = utf8; 

    看看这3个变量的作用:
    信息输入路径:client→connection→server;
    信息输出路径:server→connection→results。
    换句话说,每个路径要经过3次改变字符集编码。以出现乱码的输出为例,server里utf8的数据,传入connection转为latin1,传入results转为latin1,utf-8页面又把results转过来。如果两种字符集不兼容,比如latin1和utf8,转化过程就为不可逆的,破坏性的。

    但这里要声明一点,“SET NAMES UTF8”作用只是临时的,MySQL重启后就恢复默认了。

    接下来就说到MySQL在服务器上的配置问题了。岂不是我们每次对数据库读写都得加上“SET NAMESUTF8”,以保证数据传输的编码一致?能不能通过配置MySQL来达到那三个变量默认就为我们要想的字符集?手册上没说,我在网上也没找到答案。所以,从服务器配置的角度而言,是没办法省略掉那行代码的。
    总结:为了让你的网页能在更多的服务器上正常地显示,还是加上“SET NAMES UTF8”吧,即使你现在没有加上这句也能正常访问。

    注:根据以上文章,本人理解为,也就是说,mysql中修改了默认的编码格式,可以使得server即数据库中的数据编码格式为utf8但是无法保证connection中和results中的编码格式也为utf8因此需要加上set names utf8来使得三个地方的编码格式都统一为utf8

  • 相关阅读:
    Linux下编辑、编译、调试命令总结——gcc和gdb描述
    scanf函数读取缓冲区数据的问题
    Windows下设置Ubuntu引导项
    前端术语汇总笔记(会保持更新)
    实现动态加载一个 JavaScript 资源
    提取一个字符串中的数字,并将其转为数组
    CSS3图片倒影技术
    js函数聚合
    js继承函数封装
    联动菜单实现思路
  • 原文地址:https://www.cnblogs.com/wmm123/p/11945476.html
Copyright © 2020-2023  润新知