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和ACCESS写聊天室(五)
Oct 09 PHP
用PHP实现Ftp用户的在线管理的代码
Mar 06 PHP
PHP+apc+ajax实现的ajax_upload上传进度条代码
Jan 25 PHP
php通过文件头判断格式的方法
May 28 PHP
CI框架无限级分类+递归的实现代码
Nov 01 PHP
CI框架中类的自动加载问题分析
Nov 21 PHP
Centos 6.5下PHP 5.3安装ffmpeg扩展的步骤详解
Mar 02 PHP
2017年最新PHP经典面试题目汇总(上篇)
Mar 17 PHP
PHP多进程之pcntl_fork的实例详解
Oct 15 PHP
PHP等比例压缩图片的实例代码
Jul 26 PHP
详解PHP素材图片上传、下载功能
Apr 12 PHP
php模式设计之观察者模式应用实例分析
Sep 25 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
jQuery新闻滚动插件 jquery.roller.js
2011/06/27 Javascript
jQuery中实现动画效果的基本操作介绍
2013/04/16 Javascript
JS中使用sort结合localeCompare实现中文排序实例
2014/07/23 Javascript
Javascript设计模式之观察者模式的多个实现版本实例
2015/03/03 Javascript
JavaScript模拟实现键盘打字效果
2015/06/29 Javascript
JavaScript中的this,call,apply使用及区别详解
2016/01/29 Javascript
confirm确认对话框的实现方法总结
2016/06/17 Javascript
JavaScript判断浏览器对CSS3属性是否支持的多种方法
2016/11/13 Javascript
关于Function中的bind()示例详解
2016/12/02 Javascript
Webpack执行命令参数详解
2017/06/17 Javascript
jQuery实现倒计时功能 jQuery实现计时器功能
2017/09/19 jQuery
图片懒加载imgLazyLoading.js使用详解
2020/09/15 Javascript
使用layui 渲染table数据表格的实例代码
2018/08/19 Javascript
浅谈angular2子组件的事件传递(任意组件事件传递)
2018/09/30 Javascript
Vue组件跨层级获取组件操作
2020/07/27 Javascript
Python3基础之基本运算符概述
2014/08/13 Python
Python输出PowerPoint(ppt)文件中全部文字信息的方法
2015/04/28 Python
python用Pygal如何生成漂亮的SVG图像详解
2017/02/10 Python
TensorFlow用expand_dim()来增加维度的方法
2018/07/26 Python
纯python进行矩阵的相乘运算的方法示例
2019/07/17 Python
linux下python中文乱码解决方案详解
2019/08/28 Python
Flask中sqlalchemy模块的实例用法
2020/08/02 Python
opencv python 对指针仪表读数识别的两种方式
2021/01/14 Python
乌克兰巴士票购买网站:inBus
2021/03/12 全球购物
介绍一下HDLC(High-Level Data Link Control)高层数据链路协议
2012/01/21 面试题
EJB的角色和三个对象
2015/12/31 面试题
大专毕业生自我鉴定
2013/11/21 职场文书
电气工程及其自动化专业毕业生自荐信
2014/06/21 职场文书
化学教育专业求职信
2014/07/08 职场文书
2014年教师节演讲稿
2014/09/03 职场文书
建筑工地资料员岗位职责
2015/04/13 职场文书
责任书范本大全
2015/05/11 职场文书
2015小学教师年度考核工作总结
2015/05/12 职场文书
阿凡达观后感
2015/06/10 职场文书
辞职离别感言
2015/08/04 职场文书
2019XX公司员工考核管理制度!
2019/08/07 职场文书