MySQL中emoji字符后面的字符串被截断及Chrome中的显示问题

转发了一条微博,里面有个电池的emoji表情,导致微博页面自动抓取并存入MySQL数据库后,emoji表情及后面的所有字符串被截断舍弃,所以最后只显示出了半条微博……

搜索后发现,是因为该表情的UTF-8编码占用了4个字节(Unicode为1F50B[11111010100001011],UTF-8为F09F948B[11110000 10011111 10010100 10001011]),而MySQL的utf8默认仅支持1-3字节的编码,故出错。

解决方法是,将数据库的utf8编码升级为utf8mb4,然后PHP操作数据库前加上”SET NAMES utf8mb4″即可。

然后我发现,在手机、IE11下,该emoji均可正常显示,但是Windows的Chrome下显示为“口”,网上解决方法多为安装插件,但我又控制不了所有的浏览器,所以,我的方法是在CSS中font-family的末尾、sans-serif(或其它通常字体系列名称)的前面加上”Segoe UI Emoji”,这样根据font-family的回退规则,浏览器会自动以Segoe UI Emoji字体显示表情,从Win7开始就支持该字体了,同时不影响在其他平台的显示。

另外还发现了Chrome的另一个问题,如果使用了first-letter选择器将第一个字号调大,那么在用鼠标选取后面的文字时,会出现光标与反显不同步的现象(明明你的光标划过了某个字,但却选中了后面的一个字)。这应该是浏览器内核问题,安卓版chrome及Opera也都有选取文字不跟手的问题,但是IE正常。

#稍微学习了下字符编码问题,总结下来:

最简单的应该是ASCII码了,其用一个字节(8比特)来编码128个字符,首位是0,即0xxxxxxx。
记事本中的ANSI编码方式,对于英文文件是ASCII编码,对于简体中文文件是GB2312编码,繁体中文文件是Big5编码。

然后是Unicode,其编码符范围可以涵盖世界上所有符号。
记事本中的Unicode是用两个字节存储,顺序方式为Big endian,反过来存就是Little endian,通过在每一个文件的最前面加入表示编码顺序的字符“FE FF”或“FF FE”(以十六进制表示)区别。

UTF-8是Unicode的一种实现方式,带有控制位,可变长度,解决了Unicode存储及识别的问题。规则为:
①单字节符号,字节的第一位设为0,后面7位为这个符号的Unicode码。因此,英语字母的UTF-8编码和ASCII码相同。
②多(n)字节符号,第一个字节的前n位都设为1,第n+1位设为0,后面字节的前两位一律设为10,其余的二进制位,全部为这个符号的Unicode码,从后往前填,剩余位补零。
上面的01串即通过此规则转换得出。
记事本中UTF-8文件的开头为“EF BB BF”,ANSI文件开头无这种标识。

随便看看

本文共有18条评论

  1. 这类问题,如果落在我手上,直接放弃了,因为实在不会。不过,碰到博主,算它倒霉了,博主不弄个清楚不会罢休的,呵呵。

你好,哪位? 填写