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调用三种数据库的方法(2)
Oct 09 PHP
MySQL数据库转移,access,sql server 转 MySQL 的图文教程
Sep 02 PHP
JS 网站性能优化笔记
May 24 PHP
支持中文字母数字、自定义字体php验证码代码
Feb 27 PHP
PHPThumb PHP 图片缩略图库
Mar 11 PHP
set_include_path和get_include_path使用及注意事项
Feb 02 PHP
使用session判断用户登录用户权限(超简单)
Jun 08 PHP
ThinkPHP多表联合查询的常用方法
Mar 24 PHP
PHP中Memcache操作类及用法实例
Dec 12 PHP
CodeIgniter扩展核心类实例详解
Jan 20 PHP
PHP中的session安全吗?
Jan 22 PHP
ThinkPHP like模糊查询,like多匹配查询,between查询,in查询,一般查询书写方法
Sep 26 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 session和cookie使用说明
2010/04/07 PHP
PHP输出日历表代码实例
2015/03/27 PHP
PHP执行shell脚本运行程序不产生core文件的方法
2016/12/28 PHP
发布BlueShow v1.0 图片浏览器(类似lightbox)blueshow.js 打包下载
2007/07/21 Javascript
javascript按位非运算符的使用方法
2013/11/14 Javascript
javascript实现加载xml文件的方法
2015/11/24 Javascript
js随机生成26个大小写字母
2016/02/12 Javascript
原生JS实现平滑回到顶部组件
2016/03/16 Javascript
js 获取元素所有兄弟节点的实现方法
2016/09/06 Javascript
jQuery内容筛选选择器实例代码
2017/02/06 Javascript
bootstrap table sum总数量统计实现方法
2017/10/29 Javascript
AngularJs 终极购物车(实例讲解)
2017/11/08 Javascript
vue.js使用代理和使用Nginx来解决跨域的问题
2018/02/03 Javascript
jQuery实现DIV响应鼠标滑过由下向上展开效果示例【测试可用】
2018/04/26 jQuery
解决angular2在双向数据绑定时[(ngModel)]无法使用的问题
2018/09/13 Javascript
js字符串类型String常用操作实例总结
2019/07/05 Javascript
js实现表格数据搜索
2020/08/09 Javascript
Python抓取淘宝下拉框关键词的方法
2015/07/08 Python
Python的Django中将文件上传至七牛云存储的代码分享
2016/06/03 Python
使用PyInstaller将Python程序文件转换为可执行程序文件
2016/07/08 Python
Pandas:Series和DataFrame删除指定轴上数据的方法
2018/11/10 Python
使用Python3+PyQT5+Pyserial 实现简单的串口工具方法
2019/02/13 Python
使用pyecharts1.7进行简单的可视化大全
2020/05/17 Python
利用Python将多张图片合成视频的实现
2020/11/23 Python
字中字效果的实现【html5实例】
2016/05/03 HTML / CSS
印度购买眼镜和太阳镜网站:Coolwinks
2018/09/26 全球购物
奥林匹亚体育:Olympia Sports
2020/12/30 全球购物
.NET笔试题(20个问题)
2016/02/02 面试题
大学生毕业自我鉴定范文
2013/09/19 职场文书
各营销点岗位职责范本
2014/03/05 职场文书
给市场的环保建议书
2014/05/14 职场文书
政治学专业毕业生求职信
2014/08/11 职场文书
暑假社会实践心得体会
2014/09/02 职场文书
开平碉楼导游词
2015/02/06 职场文书
暑假开始了,你的暑假学习计划写好了吗?
2019/07/04 职场文书
你有一份《诚信考试承诺书》待领取
2019/11/13 职场文书