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备份数据库生成SQL文件并下载的函数代码
Feb 05 PHP
PHP中file_get_contents高?用法实例
Sep 24 PHP
实现PHP+Mysql无限分类的方法汇总
Mar 02 PHP
PHP使用mysqldump命令导出数据库
Apr 14 PHP
PHP环境中Memcache的安装和使用
Nov 05 PHP
PHP使用内置函数生成图片的方法详解
May 09 PHP
利用PHP自动生成印有用户信息的名片
Aug 01 PHP
PHP实现负载均衡下的session共用功能
Apr 17 PHP
浅谈laravel-admin form中的数据,在提交后,保存前,获取并进行编辑
Oct 21 PHP
PHP中关于php.ini参数优化详解
Feb 28 PHP
PHP代码加密的方法总结
Mar 13 PHP
php实现JWT验证的实例教程
Nov 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
动态新闻发布的实现及其技巧
2006/10/09 PHP
php 深入理解strtotime函数的使用详解
2013/05/23 PHP
谈谈你对Zend SAPIs(Zend SAPI Internals)的理解
2015/11/10 PHP
给WordPress的编辑后台添加提示框的代码实例分享
2015/12/25 PHP
Docker配置PHP开发环境教程
2016/12/21 PHP
TP5框架实现一次选择多张图片并预览的方法示例
2020/04/04 PHP
JS window对象的top、parent、opener含义介绍
2013/12/03 Javascript
js调试系列 初识控制台
2014/06/18 Javascript
JavaScript实现表格点击排序的方法
2015/05/11 Javascript
轻松学习Javascript闭包函数
2015/12/15 Javascript
window.open不被拦截的简单实现代码(推荐)
2016/08/04 Javascript
更靠谱的H5横竖屏检测方法(js代码)
2016/09/13 Javascript
js判断请求的url是否可访问,支持跨域判断的实现方法
2016/09/17 Javascript
jQuery实现导航滚动到指定内容效果完整实例【附demo源码下载】
2016/09/20 Javascript
angularjs 表单密码验证自定义指令实现代码
2016/10/27 Javascript
React Native之prop-types进行属性确认详解
2017/12/19 Javascript
微信小程序实现的贪吃蛇游戏【附源码下载】
2018/01/03 Javascript
vue通过style或者class改变样式的实例代码
2018/10/30 Javascript
vue.js实现左边导航切换右边内容
2019/10/21 Javascript
Vue项目中Api的组织和返回数据处理的操作
2019/11/04 Javascript
Python中序列的修改、散列与切片详解
2017/08/27 Python
python执行CMD指令,并获取返回的方法
2018/12/19 Python
python3通过selenium爬虫获取到dj商品的实例代码
2019/04/25 Python
对python中的float除法和整除法的实例详解
2019/07/20 Python
python selenium操作cookie的实现
2020/03/18 Python
如何理解python对象
2020/06/21 Python
丝芙兰巴西官方商城:SEPHORA巴西
2016/10/31 全球购物
路易威登和香奈儿手袋:LuxeDH
2017/01/12 全球购物
Bealls Florida百货商店:生活服饰、家居装饰和鞋子
2018/02/23 全球购物
巴西24小时在线药房:Drogasil
2020/06/20 全球购物
建筑院校毕业生求职信
2014/06/13 职场文书
中级会计大学生职业生涯规划书
2014/09/16 职场文书
小学一年级数学教学计划
2015/01/20 职场文书
小学中队活动总结
2015/05/11 职场文书
2016计算机专业毕业生自荐信
2016/01/28 职场文书
如何利用pygame实现打飞机小游戏
2021/05/30 Python