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中static关键字原理的学习研究分析
Jul 18 PHP
php常用ODBC函数集(详细)
Jun 24 PHP
PHP从FLV文件获取视频预览图的方法
Mar 12 PHP
PHP SESSION的增加、删除、修改、查看操作
Mar 20 PHP
php实现改变图片直接打开为下载的方法
Apr 14 PHP
PHP json_encode() 函数详解及中文乱码问题
Nov 05 PHP
PHP用户管理中常用接口调用实例及解析(含源码)
Mar 09 PHP
laravel 中如何使用ajax和vue总结
Aug 16 PHP
strpos() 函数判断字符串中是否包含某字符串的方法
Jan 16 PHP
Laravel框架Request、Response及Session操作示例
May 06 PHP
PHP常用函数之获取汉字首字母功能示例
Oct 21 PHP
thinkphp框架无限级栏目的排序功能实现方法示例
Mar 29 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+FLASH实现上传文件进度条相关文件 下载
2007/07/21 PHP
php中通过虚代理实现延迟加载的实现代码
2011/06/10 PHP
PHP及Zend Engine的线程安全模型分析
2011/11/10 PHP
php入门之连接mysql数据库的一个类
2012/04/21 PHP
php使用post数组的键值创建同名变量并赋值的方法
2015/04/03 PHP
正确的PHP匹配UTF-8中文的正则表达式
2015/05/13 PHP
php JWT在web端中的使用方法教程
2018/09/06 PHP
php生成随机数/生成随机字符串的方法小结【5种方法】
2020/05/27 PHP
Aster vs KG BO3 第一场2.19
2021/03/10 DOTA
在textarea文本域中显示HTML代码的方法
2007/03/06 Javascript
详解Javascript 装载和执行
2014/11/17 Javascript
javascript实现ecshop搜索框键盘上下键切换控制
2015/03/18 Javascript
基于replaceChild制作简单的吞噬特效
2015/09/21 Javascript
jQuery模仿单选按钮选中效果
2016/06/24 Javascript
基于jQuery实现表格的排序
2016/12/02 Javascript
从零学习node.js之搭建http服务器(二)
2017/02/21 Javascript
解决AngualrJS页面刷新导致异常显示问题
2017/04/20 Javascript
详解vue项目的构建,打包,发布全过程
2017/11/23 Javascript
vscode中vue-cli项目es-lint的配置方法
2018/07/30 Javascript
es6 filter() 数组过滤方法总结
2019/04/03 Javascript
Node.js系列之连接DB的方法(3)
2019/08/30 Javascript
使用vuex存储用户信息到localStorage的实例
2019/11/11 Javascript
vue项目中使用bpmn为节点添加颜色的方法
2020/04/30 Javascript
Python排序搜索基本算法之堆排序实例详解
2017/12/08 Python
Python3中关于cookie的创建与保存
2018/10/21 Python
Python读取系统文件夹内所有文件并统计数量的方法
2018/10/23 Python
Python GUI学习之登录系统界面篇
2019/08/21 Python
python二元表达式用法
2019/12/04 Python
python 图像的离散傅立叶变换实例
2020/01/02 Python
详解html5 canvas 微信海报分享(个人爬坑)
2018/01/12 HTML / CSS
ziaja齐叶雅官方海外旗舰店:来自波兰的天然护肤品牌
2017/01/02 全球购物
Mountain Warehouse德国官网:英国户外零售商
2019/08/11 全球购物
企业管理专业个人求职信范文
2013/09/24 职场文书
幼儿园社区活动总结
2014/07/07 职场文书
党性锻炼的心得体会
2014/09/03 职场文书
经理岗位职责范本
2015/04/15 职场文书