PHP+MySql字符问题原理分析
假如数据库已经设置了utf-8 ,php文件也设置了utf-8 ,但在php文件的查询语句中未添加了 mysql_query("set names utf8")语句,此时php页面显示正常的汉字,没有乱码。但是会发现用可视化工具连接数据库查看数据时,虽然可视化工具也已经设置了utf8编码,但在可视化工具上显示的就是乱码。因此怀疑实际上存入数据库的真实内容就是乱码,而之所以在浏览器显示正常,可能中间又经过了一个逆转化过程,把存在数据库真实乱码数据由转化为了正常数据,然后返回给浏览器,所以浏览器看上去是正常汉字,但实际上数据库中存的内容缺不是正常汉子。
原理分析:【纯属个人理解,不一定准确】
在mysql数据库中有3个变量:
character_set_client
character_set_connection
character_set_results
你可以分别理解为:客户端、连接器、返回值
客户端 :通常有cmd下的命令行,或者浏览器
连接器 :这个比较抽象,我们看不到,应该是在mysql数据库中的
返回值 :
就是以什么样的字符编码来给客户端
我们一般在cmd下set names gbk 或者php文件中 mysql_query('set names utf8'),其实就是相当于同时设置上面所说的3个变量的值为 gbk 或者 utf8 ,也就是客户端、连接器、返回值都为一样的字符编码,如果你足够耐心也可以再mysql命令行下分别设置这3个变量的值,比如:
set
character_set_client =gbk;
set character_set_connection = gbk;
set
character_set_results = gbk;
现在分析最开头提出的问题:数据库已经设置了utf-8 ,php文件也设置了utf-8 ,但未添加了mysql_query("set names utf8")语句,用浏览器查看,如果你的浏览器应该是urf8字符集,那在浏览器上显示正常汉字,但可视化的数据库连接工具显示的是乱码。我怀疑数据库中的内容就是乱码。
其实,问题应该就是出在连接器这个环节上。字符集设置有个限制,那就是字符集编码的大小,应该是这个规律: 客户端 <= 连接器 <= 服务端
那么我在说下连接器的作用,连接器就是接受客户端传来的数据,先接受保存起来,在转换成服务端所需的字符编码。比如客户端是GBK ,连接器也是GBK,服务端是UTF8,那么 连接器就会把客户端传来的GBK数据先存储起来,转换成服务器的UTF8后传给服务器。
那么回到字符集设置规律上,GBK存储汉字需要2个字节,UTF8存储汉字需要3个字节 ,如果你的客户端是UTF8,而连接器是GBK,那么就会在存储上出现问题,所以存入数据库后就会乱码【连接器接收到客户端数据是二进制码,一律认为是GBK码(但实际上客户端可能设置的是utf8码),把这个实际是utf8码的数据当成了GBK码利用公式f(x)转换为了自己认为的utf8码,也就是把真实的utf8数据进行了f(x)转换,也就成了乱码。本来如果不转换就没问题,但它多余的做了一步转换工作,所以最终存在数据库中的数据是乱码了。当我们从浏览器要求取数据时,由于连接器又进行了一步逆转换f'(x),所以数据库中的乱码数据又在页面恢复正常了】。
总结:由上面的分析可见,如果数据库已经设置了utf8编码,在浏览器页面存入数据库数据时,一定要加上mysql_query("set names utf8")语句,这样连接器才不会多余的进行一次f(x)转换,存入数据库的数据才是正常的汉字数据,否则虽然在浏览器看到的数据可能是正常汉字,但数据库中存的可能是乱码。总之,一定要保持连接器和数据库的字符集一样,而mysql_query("set names utf8")语句就是起到这个作用。
PHP+MySql字符问题原理分析的更多相关文章
- MySQL索引结构原理分析
我们在学习MySQL的时候经常会听到索引这个词,大概也知道这是什么,但是深究下去又说不出什么道道来.下面将会比较全面的介绍一下关于索引! 1 索引是什么? 这里用百度百科的一句话来说,在关系数据库中, ...
- 干货 MySQL常见的面试题 + 索引原理分析
常见的面试必备之MySQL索引底层原理分析: MySQL索引的本质 MySQL索引的底层原理 MySQL索引的实战经验 面试 1)问题:数据库中最常见的慢查询优化方式是什么? 回答:加索引 2)问题: ...
- MYSQL索引结构原理、性能分析与优化
[转]MYSQL索引结构原理.性能分析与优化 第一部分:基础知识 索引 官方介绍索引是帮助MySQL高效获取数据的数据结构.笔者理解索引相当于一本书的目录,通过目录就知道要的资料在哪里, 不用一页一页 ...
- 【转】由浅入深探究mysql索引结构原理、性能分析与优化
摘要: 第一部分:基础知识 第二部分:MYISAM和INNODB索引结构 1.简单介绍B-tree B+ tree树 2.MyisAM索引结构 3.Annode索引结构 4.MyisAM索引与Inno ...
- Mysql报错注入原理分析(count()、rand()、group by)
Mysql报错注入原理分析(count().rand().group by) 0x00 疑问 一直在用mysql数据库报错注入方法,但为何会报错? 百度谷歌知乎了一番,发现大家都是把官网的结论发一下截 ...
- Mysql数据库事务的隔离级别和锁的实现原理分析
Mysql数据库事务的隔离级别和锁的实现原理分析 找到大神了:http://blog.csdn.net/tangkund3218/article/details/51753243 InnoDB使用MV ...
- 【MySQL 原理分析】之 Trace 分析 order by 的索引原理
一.背景 昨天早上,交流群有一位同学提出了一个问题.看下图: 我不是大佬,而且当时我自己的想法也只是猜测,所以并没有回复那位同学,只是接下来自己做了一个测试验证一下. 他只简单了说了一句话,就是同样的 ...
- flink-----实时项目---day07-----1.Flink的checkpoint原理分析 2. 自定义两阶段提交sink(MySQL) 3 将数据写入Hbase(使用幂等性结合at least Once实现精确一次性语义) 4 ProtoBuf
1.Flink中exactly once实现原理分析 生产者从kafka拉取数据以及消费者往kafka写数据都需要保证exactly once.目前flink中支持exactly once的sourc ...
- 数据库MySQL 之 索引原理与慢查询优化
数据库MySQL 之 索引原理与慢查询优化 浏览目录 索引介绍方法类型 聚合索引辅助索引 测试索引 正确使用索引 组合索引 注意事项 查询计划 慢查询日志 大数据量分页优化 一.索引介绍方法类型 1. ...
随机推荐
- DI 之 3.3 更多DI的知识(陆)
3.3.1 延迟初始化Bean 延迟初始化也叫做惰性初始化,指不提前初始化Bean,而是只有在真正使用时才创建及初始化Bean. 配置方式很简单只需在<bean>标签上指定 " ...
- 指针转换(C# 编程指南)
原文地址:https://msdn.microsoft.com/zh-cn/library/etb4xxec.aspx 下表显示了预定义的隐式指针转换.隐式转换可能在多种情形下发生,包括调用方法时和在 ...
- 高性能Web服务端 PHP vs Node.js vs Nginx-Lua 的对比分析
1. ngx_lua nodejs php 比较 我在研究一阵子ngx_lua之后发现lua语法和js真的很像,同时ngx_lua模型也是单线程的异步的事件驱动的,工作原理和nodejs相同,代码甚至 ...
- python常见的模块
Python内置模块名称 功能简介 详细解释/使用示例 os 和操作系统相关 os.path — Common pathname manipulations sys 和系统相关 sys — Syste ...
- 51nod 1613翻硬币
题目链接:51nod 1613 翻硬币 知乎上的理论解法http://www.zhihu.com/question/26570175/answer/33312310 本题精髓在于奇偶性讨论. 若 n ...
- css中的zoom
CSS中zoom:1的作用兼容IE6.IE7.IE8浏览器,经常会遇到一些问题,可以使用zoom:1来解决,有如下作用:触发IE浏览器的haslayout解决ie下的浮动,margin重叠等一些问题. ...
- [python学习]结合开源库学习python
代码碎片1 #!/usr/bin/python # please add your code here! import matplotlib matplotlib.use('Agg') import ...
- 开发excel 自定义func
http://www.cnblogs.com/brooks-dotnet/archive/2011/01/16/1936871.html http://club.excelhome.net/threa ...
- Chrome plug-in 和Extension
"扩展"和"插件",其实都是软件组件的一种形式,Chrome 只不过是把两种类型的组件分别给与了专有名称,一个叫"扩展",另一个叫" ...
- asp.net core StaticFiles中间件修改wwwroot
new StaticFileOptions() { FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentD ...