假如数据库已经设置了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字符问题原理分析的更多相关文章

  1. MySQL索引结构原理分析

    我们在学习MySQL的时候经常会听到索引这个词,大概也知道这是什么,但是深究下去又说不出什么道道来.下面将会比较全面的介绍一下关于索引! 1 索引是什么? 这里用百度百科的一句话来说,在关系数据库中, ...

  2. 干货 MySQL常见的面试题 + 索引原理分析

    常见的面试必备之MySQL索引底层原理分析: MySQL索引的本质 MySQL索引的底层原理 MySQL索引的实战经验 面试 1)问题:数据库中最常见的慢查询优化方式是什么? 回答:加索引 2)问题: ...

  3. MYSQL索引结构原理、性能分析与优化

    [转]MYSQL索引结构原理.性能分析与优化 第一部分:基础知识 索引 官方介绍索引是帮助MySQL高效获取数据的数据结构.笔者理解索引相当于一本书的目录,通过目录就知道要的资料在哪里, 不用一页一页 ...

  4. 【转】由浅入深探究mysql索引结构原理、性能分析与优化

    摘要: 第一部分:基础知识 第二部分:MYISAM和INNODB索引结构 1.简单介绍B-tree B+ tree树 2.MyisAM索引结构 3.Annode索引结构 4.MyisAM索引与Inno ...

  5. Mysql报错注入原理分析(count()、rand()、group by)

    Mysql报错注入原理分析(count().rand().group by) 0x00 疑问 一直在用mysql数据库报错注入方法,但为何会报错? 百度谷歌知乎了一番,发现大家都是把官网的结论发一下截 ...

  6. Mysql数据库事务的隔离级别和锁的实现原理分析

    Mysql数据库事务的隔离级别和锁的实现原理分析 找到大神了:http://blog.csdn.net/tangkund3218/article/details/51753243 InnoDB使用MV ...

  7. 【MySQL 原理分析】之 Trace 分析 order by 的索引原理

    一.背景 昨天早上,交流群有一位同学提出了一个问题.看下图: 我不是大佬,而且当时我自己的想法也只是猜测,所以并没有回复那位同学,只是接下来自己做了一个测试验证一下. 他只简单了说了一句话,就是同样的 ...

  8. 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 ...

  9. 数据库MySQL 之 索引原理与慢查询优化

    数据库MySQL 之 索引原理与慢查询优化 浏览目录 索引介绍方法类型 聚合索引辅助索引 测试索引 正确使用索引 组合索引 注意事项 查询计划 慢查询日志 大数据量分页优化 一.索引介绍方法类型 1. ...

随机推荐

  1. Windows代码页、区域

    目录 第1章代码页    1 1 代码页    1 1.1 单字节字符集    1 1.2 双字节字符集    1 1.3 多字节字符集    1 1.4 ANSI代码页    2 2 枚举代码页   ...

  2. sap 中怎样把非限制库存转为销售订单库存?

    把非限制库存转为销售订单库存: MB1B 移动类型413 把销售订单库存转为非限制库存: MB1B移动类型411 E 切记!

  3. mathematics

    二倍角公式 史济怀-数学分析1-2003-09-19_2.asx-在线播放-优酷网,视频高清在线观看http://v.youku.com/v_show/id_XMTMzMDU1MTgw.html 国立 ...

  4. [redis] Redis 常用命令

    redis命令文档:http://doc.redisfans.com/index.html 1. redis查看当前所有的key KEYS * 模糊匹配keykeys 模糊字符串*   2. 查看当前 ...

  5. 1029c语言文法2理解

    program → external_declaration | program external_declaration <程序>→ <外部声明>|<程序>< ...

  6. Path Sum [LeetCode]

    Problem Description: http://oj.leetcode.com/problems/path-sum/ Pretty easy. /** * Definition for bin ...

  7. Linux sed命令实例详解

    简介 sed 是一种在线编辑器,它一次处理一行内容.处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”(pattern space),接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的 ...

  8. 语句:分支语句、switch case ——7月22日

    语句的类型包括:声明语句.表达式语句.选择语句.循环语句.跳转语句.异常语句 1.声明语句引:入新的变量或常量. 变量声明可以选择为变量赋值. 在常量声明中必须赋值. 例如: int i = 0;// ...

  9. long long 与 _int64

    本文讨论的是五种常用的C/C++编译器对64位整型的支持,这五种编译器分别是gcc(mingw32),g++(mingw32),gcc(linux i386),g++(linux i386),Micr ...

  10. TokuDB介绍——本质是分形树(一个叶子4MB)+缓存减少写操作

    其性能特点见:http://www.cnblogs.com/billyxp/p/3567421.html TokuDB 是一个高性能.支持事务处理的 MySQL 和 MariaDB 的存储引擎.Tok ...