PHP中遇到BOM、<feff>编码导致json_decode函数无法解析问题 |
昨天同事遇到一个奇怪的问题,就是以下代码,无法通过JSON校验,也无法通过PHP的json_decode函数解析 。 复制代码 代码如下: [ { "title": "", "pinyin": "" } ] 可能聪明的你已经猜到其中包含有不看见的特殊字符,在vim下查看: 复制代码 代码如下: [ { <feff>"title": "", "pinyin": "" } ] 发现在“title”前面有一个字符<feff>,如果你之前了解过BOM,应该知道这个特殊字符就是BOM,关于其介绍可以参考另一篇文章:计算机中的字符串编码、乱码、BOM等问题详解.
复制代码 代码如下: 0000000: 5b 0a 20 20 20 20 7b 0a 20 20 20 20 20 20 20 20 [. {. 0000010: ef bb bf 22 74 69 74 6c 65 22 3a 20 22 22 2c 0a ..."title": "",. 0000020: 20 20 20 20 20 20 20 20 22 70 69 6e 79 69 6e 22 "pinyin" 0000030: 3a 20 22 22 0a 20 20 20 20 7d 0a 5d 0a : "". }.]. 可以看到刚才那个"title"前面的特殊字符十六进制为:ef bb bf,正是标记UTF-8的BOM 。BOM的含义如下: 复制代码 代码如下: 开头字节 Charset/encoding EF BB BF UTF-8 FE FF UTF-16/UCS-2, little endian(UTF-16LE) FF FE UTF-16/UCS-2, big endian(UTF-16BE) FF FE 00 00 UTF-32/UCS-4, little endian. 00 00 FE FF UTF-32/UCS-4, big-endia 发现问题解决就很容易了,查找删除BOM就OK了,linux下BOM相关的命令有: VIM的BOM操作 复制代码 代码如下: #添加BOM :set bomb #删除BOM :set nobomb #查询BOM :set bomb? 查找UTF-8编码中的BOM 复制代码 代码如下: grep -I -r -l $\xEF\xBB\xBF /path 还可以在svn的钩子中禁止提交BOM(以下代码来自网络,没校验) 复制代码 代码如下: #!/bin/sh REPOS="$1" SVNLOOK=/usr/bin/svnlook FILES=`$SVNLOOK changed -t "$TXN" "$REPOS" | awk {print $2}` for FILE in $FILES; do if echo $CONTENT | head -c 3 | xxd -i | grep -q 0xef, 0xbb, 0xbf; then 最后提醒大家在wowdows下最好别使用记事本等会自动添加BOM的编辑器修改代码,容易引发一些问题 。 |