一 字符,字节以及编码
字符是人们常用的一些记号,比如"1", "汉", "お","℃"等等,包括各种语系的语言和一些符号都可以被称为字符。
字节是计算机存储数据的存储单元,是一个8位的二进制数,所以最多只能表示256个数字(0-255)。
编码是大家对计算机如何使用字节来表示一个字符的约定,可分为ASCII编码,ANSI编码(本地化编码),UNICODE编码(国际化编码)三种。
1.ASCII编码:单字节编码。
最初的编码,由一个字节组成,因此只能表示256个字符,但只表示0-9,a-z,A-Z,和一些加减乘除百分号,够老美用了。
后来ISO国际标准组织以ASCII编码为基础,约定了ISO 8859-1编码,又称Latin1编码。(Mysql的默认存储编码)
2.ANSI编码:多字节编码。
如果只有ASCII编码的话,计算机岂不只能表示英文字母和数字还有几个加减乘除号,中文怎么办,阿拉伯文怎么办,日文怎么办?
由于一个字节只能表示255个数字,所以中国约定了GBK编码规则,约定用0x80-0xFF范围内的某两个字节来表示某一个中文字符。
日本约定了JIS编码规则,他们约定0x80-0xFF范围内的某两个字节来表示某个日文字符。
台湾约定了BIG5编码规则,约定0x80-0xFF范围内的某两个字节表示某个繁体中文字符。
所以我们拿到了一个ANSI字节串的时候,我们还必须知道这个字节串的编码,才能将这个字节串转换成相应国家的字符串。
3.UNICODE编码:宽字节编码
ANSI编码有很多种,但是都只是规定自己国家的语言,这时候出现了UNICODE编码,该编码类似于ANSI,使用多个字节表示一个字符,UNICODE编码把世界上各种主要语言都进行了编码,当然UNICDOE编码也出现了很多种编码方案,比如使用8个二进制位的UTF8以及使用16个二进制位的UTF16等等。
二 有关MYSQL的编码问题
1 MYSQL的默认编码为latin1,就是那个只能存储英文字母,数字,和几个鬼画符的编码。
2 MYSQL的字符集设定有以下几项
character_set_client
character_set_connection
character_set_database
character_set_results
character_set_server
character_set_system
3 通过修改my.ini配置文件中的default-character-set=utf8可以将database,server,system修改为utf8,但无法修改client,connection,results。
运行 "SET NAMES UTF8" 之后,client,connection,result即为UTF8。
4 关于mysql的编码的一些备忘知识:
通过设置character_set_client,告诉Mysql,存进MYSQL的数据是什么编码方式。如果存进去的是gbk,而数据列的格式为utf8,则mysql将gbk转换成utf8后存入。
通过设置character_set_results,告诉Mysql,PHP需要取什么样编码的数据。
通过设置character_set_connection,告诉Mysql,PHP执行的查询语句中的文本,使用什么编码。
因此,要提高效率的话,尽量将php与mysql设置为相同的字符集,避免了编码的转换。
Mysql可以设置服务器级字符集、数据库级字符集、数据表级字符集、表列的字符集,实际上,最终使用字符集的地方是存储字符的列。
通常情况下,只需设置服务器级的字符集,其它的数据库级,表级,以及列级的字符集,都继承自服务器级字符集。
5 PHP+MYSQL乱码的常见原因:
数据库使用UTF8格式存储数据,但php读取数据时未执行"SET NAMES UTF8"语句,所以character_set_results的值为latin1,所以读取数据时,mysql将utf8格式的数据转换成为了latin1格式,latin1根本无法表示多字节字符,从而导致从数据库读到很多乱码。
6 网页的乱码问题
网页要保证页面源文件的编码和META里面声明的charset的编码一致,就不会产生乱码。
但是注意META要写在TITLE的前面,因为META中指定了编码,TITLE如果是中文,而且在META前面,浏览器在解析到中文TITLE的时候因为还没解析到META,所以不知道这个页面应该用什么编码呈现,从而导致了出现问题。