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 相关文章推荐
打造计数器DIY三步曲(上)
Oct 09 PHP
使用php4加速网络传输
Oct 09 PHP
PHP取进制余数函数代码
Jan 19 PHP
php去除HTML标签实例
Nov 06 PHP
PHP网页游戏学习之Xnova(ogame)源码解读(十二)
Jun 25 PHP
php连接mysql数据库
Mar 21 PHP
PHP+Redis 消息队列 实现高并发下注册人数统计的实例
Jan 29 PHP
php通过各种函数判断0和空
Jul 04 PHP
laravel获取不到session的三种解决办法【推荐】
Sep 16 PHP
PHP连接及操作PostgreSQL数据库的方法详解
Jan 30 PHP
php实现微信小程序授权登录功能(实现流程)
Nov 13 PHP
在 Laravel 6 中缓存数据库查询结果的方法
Dec 11 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
中国站长站 For Dede4.0 采集规则
2007/05/27 PHP
php中最简单的字符串匹配算法
2014/12/16 PHP
Laravel自定义 封装便捷返回Json数据格式的引用方法
2019/09/29 PHP
js表数据排序 sort table data
2009/02/18 Javascript
Javascript 解疑
2009/11/11 Javascript
YUI模块开发原理详解
2013/11/18 Javascript
Javascript基础教程之定义和调用函数
2015/01/18 Javascript
js进行表单验证实例分析
2015/02/10 Javascript
Javascript代码实现仿实例化类
2015/04/03 Javascript
深入分析jsonp协议原理
2015/09/26 Javascript
基于Jquery和html5实现炫酷的3D焦点图动画
2016/03/02 Javascript
Angular-Touch库用法示例
2016/12/22 Javascript
基于代数方程库Algebra.js解二元一次方程功能示例
2017/06/09 Javascript
BootStrap 页签切换失效的解决方法
2017/08/17 Javascript
AngularJs1.x自定义指令独立作用域的函数传入参数方法
2018/10/09 Javascript
layui 监听select选择 获取当前select的ID名称方法
2019/09/24 Javascript
vue实现权限控制路由(vue-router 动态添加路由)
2019/11/04 Javascript
Vue+Vant 图片上传加显示的案例
2020/11/03 Javascript
一篇文章看懂JavaScript中的回调
2021/01/05 Javascript
线程和进程的区别及Python代码实例
2015/02/04 Python
介绍Python中内置的itertools模块
2015/04/29 Python
python实现合并两个数组的方法
2015/05/16 Python
Python的Flask框架中集成CKeditor富文本编辑器的教程
2016/06/13 Python
Python新手们容易犯的几个错误总结
2017/04/01 Python
Python标准库itertools的使用方法
2020/01/17 Python
python中adb有什么功能
2020/06/07 Python
Python轻量级web框架bottle使用方法解析
2020/06/13 Python
Pedro官网:新加坡时尚品牌
2019/08/27 全球购物
户外婚礼策划方案
2014/02/08 职场文书
优秀教师工作感言
2014/02/16 职场文书
竞聘书模板
2014/03/31 职场文书
幼儿园保育员岗位职责
2014/04/13 职场文书
大学学生会辞职信
2015/05/13 职场文书
贷款收入证明范本
2015/06/12 职场文书
初一语文教学反思
2016/03/03 职场文书
zabbix如何添加监控主机和自定义监控项
2022/08/14 Servers