前后端交互过程当中的编码

原由

最近在写PHP,自身对PHP不太闇练。然后碰到编码这个题目,搅扰了大半天,干脆,体系探究处置惩罚一番。

前后端交互历程当中触及的编码

  1. Browser cilent: 起首,浏览器的设置里有设置编码花样,平常设置为UTF-8。

  2. AJAX request: AJAX异步要求的历程当中能够设置编码,contentType:"application/x-www-form-urlencoded; charset=utf-8"

  3. PHP cilent: PHP经由历程$_POST这个全局变量吸收前端POST过来的数据,编码花样为AJAX在要求头中设置的charset=utf-8,PHP操纵的历程当中能够经由历程iconv函数库自行转码,比方iconv("UTF-8","GB2312//IGNORE",$data)

  4. connection: 在PHP与数据库衔接的历程当中能够设置connection历程当中运用的编码花样,比方CodeIgniter框架能够在数据库配置文件database.php中,设置'char_set' => 'latin1'

  5. databases: 数据会先把数据从php客户端的编码转为转为connection中设置的编码,再以字撙节的情势传输并插进去数据库。

字符编码

常常使用的编码分为

  • UTF-8 万国码,就是它是一种变长的编码体式格局

  • latin1 又称“西欧言语”,是mysql数据库默许设置。为单字节编码

  • gb2312 一共收录了7445个字符,包含6763个汉字和682个别的标记。

  • GBK 汉字内码扩大范例,支撑繁体与简体和许多标记

UTF-8

走上国际化就靠它了。如今引荐运用UTF-8,如许外国人翻开我们的网站的时刻不需要转码,直接就可以运用。
不多说了,人人都熟悉。

看一下他的编码特质
UTF-8的设想有以下的多字符组序列的特质

  • 单字节字符的最高有用比特永久为0。

  • 多字节序列中的首个字符组的几个最高有用比特决议了序列的长度。最高有用位为110的是2字节序列,而1110的是三字节序列,云云类推。

  • 多字节序列中其他的字节中的首两个最高有用比特为10。

UTF-8的这些特质,保证了一个字符的字节序列不会包含在另一个字符的字节序列中。这确保了以字节为基本的部份字符串比对(sub-string match)
要领能够适用于在笔墨中搜刮字或词。有些比较旧的可变长度8位编码(如Shift JIS)没有这个特质,故字符串比对的算法变得相称庞杂。虽然这增加了UTF-8
编码的字符串的信息冗余,然则利多于弊。别的,数据压缩并不是Unicode的目标,所以不可等量齐观。纵然在发送历程当中有部份字节因毛病或滋扰而完整丧失,
照样有能够在下一个字符的出发点从新同步,令受损局限受到限制。

另一方面,由于其字节序列设想,假如一个疑似为字符串的序列被考证为UTF-8编码,那末我们能够有把握地说它是UTF-8字符串。一段两字节随机序列恰巧为正当的UTF-8而非ASCII的几率为32分1。关于三字节序列的几率为256分1,对更长的序列的几率就更低了。

latin1

latin1编码是单字节编码,向下兼容ASCII,其编码局限是0x00-0xFF,0x00-0x7F之间完整和ASCII一致,0x80-0x9F之间是控制字符,0xA0-0xFF之间是笔墨标记。

由于latin1编码局限运用了单字节内的一切空间,在支撑latin1的体系中传输和存储其他任何编码的字撙节都不会被扬弃。换言之,把其他任何编码的字撙节看成latin1编码对待都没有题目。
这是个很主要的特征,MySQL数据库默许编码是Latin1就是利用了这个特征,latin1编码是一个8位的容器。

把一个gbk编码的串写入latin1的表,不会有任何题目,保留的是一成不变的字撙节,从表中读取已写入的串也不会有任何题目,且读出的字撙节就和当初写入的完整一致。

读取出来今后,假如在终端下,就会明白成locale范例(假如locale系gbk,当时写入的gbk中文串可正常回显)读取出来今后,假如要写入文件,则文件编码体式格局即当时写入的字撙节编码,如gbk写入的,读出存入文件后,文件编码也是gbk!
然则假如混着写(utf-8 + gbk),那编辑器就犯蒙了,就能够会显现会有乱码。

固然,基于可保护的角度,照样一致为UTF-8编码花样,以避免涌现乱码。

GBK与gb2312

由于汗青缘由,许多网页和数据库依旧运用这个编码花样
应当逐渐晋级为UTF-8。

文件编码

每一个文件都设置了其编码的花样,大部份引荐运用UTF-8。

VIM文件编码示例

一个文本文件,vim翻开的时刻按某种编码A翻开,转换成某种编码B,然后保留的时刻转换成另一种编码C,其他文本编辑器相似,能够没有vim这么能够设置和自动完成。
编码B:关于全部文件没有影响,只是事关显现的,就是vim与操纵体系交互时刻运用的编码。

编码A:运用 set fileencodings=ucs-bom,utf-8,gbk,cp936,latin-1设置。vim 根据设置的递次搜检检测文件的编码。由于某些编码里不存在某些二进制序列的组合,所以假如检测到就以为不是这类编码,搜检下一种编码,不然就以为是这一种。由于latin-1能够涌现任何二进制序列的组合,所以假如放到第一个,那末将永久以latin-1显现。

在平常的二进制文件里是不存在字符编码的标记的。然则Unicode内里有个特别叫做零宽度空格(FEFF)而FFFE是不存在的编码,所以在Unicode的规范里能够工资的在最先到场这个字符(这个字符在任何字体下都是没有宽度的,在中笔墨符内里没有任何的结果跟没有一样,是为了照应东南亚某些言语的显现而设置的)。如许就便于文本编辑器搜检字符和字节递次,然则在代码里include这类文件常常会出题目(这但是个大坑,编译器会以为这是一个不法字符,但是你又看不到)。

编码B:set fileencoding=utf-8,保留时刻运用的编码,保留的时刻自动转换为另一种编码。然则假如一最先翻开的时刻就辨认错了编码,再转换的时刻一个不存在的字符也是不会完转换的。

参考资料

  1. mysql的latin1 支撑中文

  2. UTF-8维基百科

  3. VIM 文件编码辨认与乱码处置惩罚

WilsonLiu’s blog首发地点:http://blog.wilsonliu.cn

    原文作者:WilsonLiu95
    原文地址: https://segmentfault.com/a/1190000006063607
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞