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 应用程序安全防范技术研究
Sep 25 PHP
Can't create/write to file 'C:\WINDOWS\TEMP\...MYSQL报错解决方法
Jun 30 PHP
php array_filter除去数组中的空字符元素
Jun 21 PHP
yii实现级联下拉菜单的方法
Jul 31 PHP
PHP fastcgi模式上传大文件(大约有300多K)报错
Sep 28 PHP
在Windows XP下安装Apache+MySQL+PHP环境
Feb 22 PHP
理解PHP中的Session及对Session有效期的控制
Jan 08 PHP
ThinkPHP使用getlist方法实现数据搜索功能示例
May 08 PHP
PHP简单装饰器模式实现与用法示例
Jun 22 PHP
php类自动装载、链式操作、魔术方法实现代码
Jul 23 PHP
PHP实现动态删除XML数据的方法示例
Mar 30 PHP
PHP实现给定一列字符,生成指定长度的所有可能组合示例
Jun 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
php查询mysql大量数据造成内存不足的解决方法
2015/03/04 PHP
WordPress开发中短代码的实现及相关函数使用技巧
2016/01/05 PHP
jQuery EasyUI API 中文文档 - Menu菜单
2011/10/03 Javascript
JS获取当前网址、主机地址项目根路径
2013/11/19 Javascript
jquery对ajax的支持介绍
2013/12/10 Javascript
用jquery模仿的a的title属性的例子
2014/10/22 Javascript
node.js中的console.info方法使用说明
2014/12/09 Javascript
AngularJS基础 ng-value 指令简单示例
2016/08/03 Javascript
深入浅出es6模板字符串
2017/08/26 Javascript
JS如何设置元素样式的方法示例
2017/08/28 Javascript
微信小程序使用wx.request请求服务器json数据并渲染到页面操作示例
2019/03/30 Javascript
React中阻止事件冒泡的问题详析
2019/04/12 Javascript
Angular中innerHTML标签的样式不起作用的原因解析
2019/06/18 Javascript
Vue  webpack 项目自动打包压缩成zip文件的方法
2019/07/24 Javascript
JS变量提升原理与用法实例浅析
2020/05/22 Javascript
Javascript执行上下文顺序的深入讲解
2020/11/04 Javascript
python中反射用法实例
2015/03/27 Python
python实现下载文件的三种方法
2017/02/09 Python
Python实现螺旋矩阵的填充算法示例
2017/12/28 Python
Python基于opencv调用摄像头获取个人图片的实现方法
2019/02/21 Python
python使用opencv在Windows下调用摄像头实现解析
2019/11/26 Python
pycharm配置QtDesigner的超详细方法
2021/01/25 Python
Berghaus官网:户外服装和设备,防水服
2020/01/17 全球购物
高三学习决心书
2014/03/11 职场文书
颁奖典礼主持词
2014/03/25 职场文书
土建专业大学生自荐信范文
2014/04/09 职场文书
庆六一文艺汇演活动方案
2014/08/26 职场文书
群众路线个人对照检查材料
2014/09/23 职场文书
工程合作意向书范本
2015/05/09 职场文书
电影地道战观后感
2015/06/04 职场文书
运动会通讯稿300字
2015/07/20 职场文书
2016基督教会圣诞节开幕词
2016/03/04 职场文书
成人成长感言如何写?
2019/08/16 职场文书
《悲惨世界》:比天空更广阔的是人的心灵
2020/01/16 职场文书
Python通过loop.run_in_executor执行同步代码 同步变为异步
2022/04/11 Python
详解Redis的三种常用的缓存读写策略步骤
2022/05/06 Redis