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 COOKIE设置为浏览器进程
Jun 21 PHP
PHP set_time_limit(0)长连接的实现分析
Mar 02 PHP
PHP缓存技术的使用说明
Aug 06 PHP
支持中文字母数字、自定义字体php验证码代码
Feb 27 PHP
PHP eval函数使用介绍
Dec 08 PHP
带密匙的php加密解密示例分享
Jan 29 PHP
PHP调试函数和日志记录函数分享
Jan 31 PHP
php使用GD库创建图片缩略图的方法
Jun 10 PHP
浅谈Laravel中的一个后期静态绑定
Aug 11 PHP
PHP+MySQL使用mysql_num_rows实现模糊查询图书信息功能
May 31 PHP
PHP一致性hash分布式算法封装类定义与用法示例
Aug 04 PHP
php实现的PDO异常处理操作分析
Dec 27 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实现分页的一个示例
2006/10/09 PHP
小偷PHP+Html+缓存
2006/11/25 PHP
php 判断是否是中文/英文/数字示例代码
2013/09/30 PHP
php生成RSS订阅的方法
2015/02/13 PHP
PHP使用DirectoryIterator显示下拉文件列表的方法
2015/03/13 PHP
php按字符无乱码截取中文的方法
2015/03/27 PHP
PHP小偷程序的设计与实现方法详解
2016/10/15 PHP
iOS+PHP注册登录系统 PHP部分(上)
2016/12/26 PHP
Javascript中的var_dump函数实现代码
2009/09/07 Javascript
利用jquery包将字符串生成二维码图片
2013/09/12 Javascript
jquery select 设置默认选中的示例代码
2014/02/07 Javascript
Node.js中防止错误导致的进程阻塞的方法
2016/08/11 Javascript
js编写选项卡效果
2017/05/23 Javascript
基于jquery trigger函数无法触发a标签的两种解决方法
2018/01/06 jQuery
Vue.set()实现数据动态响应的方法
2018/02/07 Javascript
vue移动端实现下拉刷新
2018/04/22 Javascript
vue中如何让子组件修改父组件数据
2018/06/14 Javascript
js+css实现红包雨效果
2018/07/12 Javascript
Vue加载组件、动态加载组件的几种方式
2018/08/31 Javascript
js实现按钮开关单机下拉菜单效果
2018/11/22 Javascript
es6基础学习之解构赋值
2018/12/10 Javascript
JS实现将对象转化为数组的方法分析
2019/01/21 Javascript
微信小程序开发的基本流程步骤
2019/01/31 Javascript
js实现盒子移动动画效果
2020/08/09 Javascript
详解Python3中的Sequence type的使用
2015/08/01 Python
Python cookbook(数据结构与算法)从序列中移除重复项且保持元素间顺序不变的方法
2018/03/13 Python
解决tensorflow测试模型时NotFoundError错误的问题
2018/07/27 Python
解决pyttsx3无法封装的问题
2018/12/24 Python
Python 一键制作微信好友图片墙的方法
2019/05/16 Python
python实时检测键盘输入函数的示例
2019/07/17 Python
团日活动策划书
2014/02/01 职场文书
驾驶员安全责任书范本
2014/07/24 职场文书
2014党的群众路线教育实践活动学习心得体会
2014/10/31 职场文书
认真学习保证书
2015/02/26 职场文书
大学生自荐信怎么写
2015/03/26 职场文书
python基于机器学习预测股票交易信号
2021/05/25 Python