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 实例化类的一点摘记
Mar 23 PHP
Cakephp 执行主要流程
Mar 24 PHP
php反射应用示例
Feb 25 PHP
php获取bing每日壁纸示例分享
Feb 25 PHP
ThinkPHP CURD方法之limit方法详解
Jun 18 PHP
win平台安装配置Nginx+php+mysql 环境
Jan 12 PHP
PHP实现补齐关闭的HTML标签
Mar 22 PHP
PHP文件上传操作实例详解
Sep 27 PHP
使用php实现网站验证码功能【推荐】
Feb 09 PHP
关于 Laravel Redis 多个进程同时取队列问题详解
Dec 25 PHP
PHP htmlentities()函数用法讲解
Feb 25 PHP
PHP 对接美团大众点评团购券(门票)的开发步骤
Apr 03 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初学者常见问题集合 修正版(21问答)
2010/03/23 PHP
php分页代码学习示例分享
2014/02/20 PHP
php源码分析之DZX1.5加密解密函数authcode用法
2015/06/17 PHP
PHP单链表的实现代码
2016/07/05 PHP
PHP数据分析引擎计算余弦相似度算法示例
2017/08/08 PHP
完整显示当前日期和时间的JS代码
2007/09/17 Javascript
Javascript匿名函数的一种应用 代码封装
2010/06/27 Javascript
extjs关于treePanel+chekBox全部选中以及清空选中问题探讨
2013/04/02 Javascript
Jquery 改变radio/checkbox选中状态,获取选中的值(示例代码)
2013/12/12 Javascript
用js代码改变单选框选中状态的简单实例
2013/12/18 Javascript
js中的如何定位固定层的位置
2014/06/15 Javascript
jQuery的基本概念与高级编程
2015/05/14 Javascript
再JavaScript的jQuery库中编写动画效果的指南
2015/08/13 Javascript
利用jQuery实现漂亮的圆形进度条倒计时插件
2015/09/30 Javascript
JavaScript事件学习小结(五)js中事件类型之鼠标事件
2016/06/09 Javascript
js重写方法的简单实现
2016/07/10 Javascript
利用jsonp跨域调用百度js实现搜索框智能提示
2016/08/24 Javascript
Vuejs第十篇之vuejs父子组件通信
2016/09/06 Javascript
js中json处理总结之JSON.parse
2016/10/14 Javascript
vue-cli创建的项目,配置多页面的实现方法
2018/03/15 Javascript
vue如何判断dom的class
2018/04/26 Javascript
JavaScript实现构造json数组的方法分析
2018/08/17 Javascript
小程序点击图片实现自动播放视频
2020/05/29 Javascript
Vuejs监听vuex中值的变化的方法示例
2018/12/02 Javascript
JS简单判断是否在微信浏览器打开的方法示例
2019/01/08 Javascript
深入探索VueJS Scoped CSS 实现原理
2019/09/23 Javascript
[56:42]VP vs RNG 2019国际邀请赛小组赛 BO2 第二场 8.15
2019/08/17 DOTA
python正则表达式的使用
2017/06/12 Python
Python操作excel的方法总结(xlrd、xlwt、openpyxl)
2019/09/02 Python
利于python脚本编写可视化nmap和masscan的方法
2020/12/29 Python
2015年底工作总结范文
2015/05/15 职场文书
幼儿园托班开学寄语(2016秋季)
2015/12/03 职场文书
慰问信的写作格式及范文!
2019/06/24 职场文书
【超详细】八大排序算法的各项比较以及各自特点
2021/03/31 Python
redis配置文件中常用配置详解
2021/04/14 Redis
SQL 尚未定义空闲 CPU 条件 - OnIdle 作业计划将不起任何作用
2021/06/30 SQL Server