PHP中遇到BOM、编码导致json_decode函数无法解析问题


Posted in PHP onJuly 02, 2014

昨天同事遇到一个奇怪的问题,就是以下代码,无法通过JSON校验,也无法通过PHP的json_decode函数解析。

[

    {

        "title": "",

        "pinyin": ""

    }

]

可能聪明的你已经猜到其中包含有不看见的特殊字符,在vim下查看:
[

    {

        <feff>"title": "",

        "pinyin": ""

    }

]

发现在“title”前面有一个字符<feff>,如果你之前了解过BOM,应该知道这个特殊字符就是BOM,关于其介绍可以参考另一篇文章:计算机中的字符串编码、乱码、BOM等问题详解.

在Linux下通过xxd命令查看文件内容的十六进制:

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"

TXN="$2"
SVNLOOK=/usr/bin/svnlook
FILES=`$SVNLOOK changed -t "$TXN" "$REPOS" | awk {'print $2'}`
for FILE in $FILES; do

    CONTENT=`$SVNLOOK cat -t "$TXN" "$REPOS" "$FILE"`
    if echo $CONTENT | head -c 3 | xxd -i | grep -q '0xef, 0xbb, 0xbf'; then

        echo "BOM!" 1>&2

        exit 1

    fi

done

最后提醒大家在wowdows下最好别使用记事本等会自动添加BOM的编辑器修改代码,容易引发一些问题。
PHP 相关文章推荐
用PHP 4.2书写安全的脚本
Oct 09 PHP
支持oicq头像的留言簿(二)
Oct 09 PHP
php判断输入不超过mysql的varchar字段的长度范围
Jun 24 PHP
PHP抓取、分析国内视频网站的视频信息工具类
Apr 02 PHP
PHP面向对象程序设计之接口用法
Aug 20 PHP
php批量添加数据与批量更新数据的实现方法
Dec 16 PHP
php实现模拟post请求用法实例
Jul 11 PHP
详细解读PHP中接口的应用
Aug 12 PHP
Symfony2中被遗弃的getRequest()方法分析
Mar 17 PHP
django中的ajax组件教程详解
Oct 18 PHP
yii2 开发api接口时优雅的处理全局异常的方法
May 14 PHP
laravel框架语言包拓展实现方法分析
Nov 22 PHP
php foreach正序倒序输出示例代码
Jul 01 #PHP
浅析ThinkPHP的模板输出功能
Jul 01 #PHP
ThinkPHP中的系统常量和预定义常量集合
Jul 01 #PHP
ThinkPHP实现多数据库连接的解决方法
Jul 01 #PHP
ThinkPHP快速入门实例教程之数据分页
Jul 01 #PHP
ThinkPHP框架实现session跨域问题的解决方法
Jul 01 #PHP
ThinkPHP的模版中调用session数据的方法
Jul 01 #PHP
You might like
星际争霸 Starcraft 秘技补丁
2020/03/14 星际争霸
新手学PHP之数据库操作详解及乱码解决!
2007/01/02 PHP
PHP统计二维数组元素个数的方法
2013/11/12 PHP
基于PHP常用文件函数和目录函数整理
2017/08/17 PHP
基于swoole实现多人聊天室
2018/06/14 PHP
laravel 框架实现无限级分类的方法示例
2019/10/31 PHP
自定义右键属性覆盖浏览器默认右键行为实现代码
2013/02/02 Javascript
禁止空格提交表单的js代码
2013/11/17 Javascript
js获取select默认选中的Option并不是当前选中值
2014/05/07 Javascript
Jquery对select的增、删、改、查操作
2015/02/06 Javascript
提交按钮的name='submit'引起的js失效问题及原因
2015/02/25 Javascript
js判断复选框是否选中及选中个数的实现代码
2016/05/30 Javascript
[02:06]DOTA2肉山黑名单魔法终结者 敌法师中文配音鉴赏
2013/06/17 DOTA
python基础教程之数字处理(math)模块详解
2014/03/25 Python
bat和python批量重命名文件的实现代码
2016/05/19 Python
matplotlib调整子图间距,调整整体空白的方法
2018/08/03 Python
python config文件的读写操作示例
2019/09/27 Python
如何打包Python Web项目实现免安装一键启动的方法
2020/05/21 Python
Python绘图实现台风路径可视化代码实例
2020/10/23 Python
使用CSS3来代替JS实现交互
2017/08/10 HTML / CSS
通过HTML5规范搞定i、em、b、strong元素的区别
2017/03/04 HTML / CSS
耐克亚太地区:Nike APAC
2019/12/07 全球购物
金讯Java笔试题目
2013/06/18 面试题
利达恒信公司.NET笔试题面试题
2016/03/05 面试题
线程问题:wait()方法是定义在哪个类里面
2015/07/07 面试题
酒吧副总经理岗位职责
2013/12/10 职场文书
学徒工职责
2014/03/06 职场文书
一岗双责责任书
2014/04/15 职场文书
5.12护士节演讲稿
2014/04/30 职场文书
初中学校军训方案
2014/05/09 职场文书
高中课前三分钟演讲稿
2014/08/18 职场文书
秦兵马俑导游词
2015/02/02 职场文书
2015暑假打工实践报告
2015/07/13 职场文书
2016年端午节红领巾广播稿
2015/12/18 职场文书
PL350与SW11的比较
2021/04/22 无线电
Python数据分析之pandas读取数据
2021/06/02 Python