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中实现简单的ACL 完结篇
Sep 07 PHP
PHP中的strtr函数使用介绍(str_replace)
Oct 20 PHP
七款最流行的PHP本地服务器分享
Feb 19 PHP
php不允许用户提交空表单(php空值判断)
Nov 12 PHP
百度工程师讲PHP函数的实现原理及性能分析(三)
May 13 PHP
WordPress中给媒体文件添加分类和标签的PHP功能实现
Dec 31 PHP
PHP4和PHP5版本下解析XML文档的操作方法实例分析
May 20 PHP
使用PHPExcel导出Excel表
Sep 08 PHP
php使用scandir()函数扫描指定目录下所有文件示例
Jun 08 PHP
PHP网页缓存技术优点及代码实例
Jul 29 PHP
PHP实现长轮询消息实时推送功能代码实例讲解
Feb 26 PHP
PHP使用非对称加密算法RSA
Apr 21 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验证码(支持中文)
2007/02/14 PHP
基于PHP如何把汉字转化为拼音
2015/12/11 PHP
Zend Framework动作助手Redirector用法实例详解
2016/03/05 PHP
PHP使用curl_multi实现并发请求的方法示例
2018/04/29 PHP
PHP实现基于3DES算法加密解密字符串示例
2018/08/24 PHP
php如何计算两坐标点之间的距离
2018/12/29 PHP
Jquery Ajax学习实例7 Ajax所有过程事件分析示例
2010/03/23 Javascript
很棒的学习jQuery的12个网站推荐
2011/04/28 Javascript
innerText 使用示例
2014/01/23 Javascript
JS+CSS实现六级网站导航主菜单效果
2015/09/28 Javascript
jQuery实现批量判断表单中文本框非空的方法(2种方法)
2015/12/09 Javascript
jQuery控制frames及frame页面JS的方法
2016/03/08 Javascript
BootStrap的弹出框(Popover)支持鼠标移到弹出层上弹窗层不隐藏的原因及解决办法
2016/04/03 Javascript
详解JavaScript中的自定义事件编写
2016/05/10 Javascript
artDialog+plupload实现多文件上传
2016/07/19 Javascript
Angular2 路由问题修复详解
2017/03/01 Javascript
基于Vue.js实现tab滑块效果
2017/07/23 Javascript
ES6关于Promise的用法详解
2018/05/07 Javascript
React 项目迁移 Webpack Babel7的实现
2018/09/12 Javascript
vue的过滤器filter实例详解
2018/09/17 Javascript
详解puppeteer使用代理
2018/12/27 Javascript
关于vue-cli 3配置打包优化要点(推荐)
2019/04/22 Javascript
微信小程序如何实现全局重新加载
2019/06/05 Javascript
NodeJS 文件夹拷贝以及删除功能
2019/09/03 NodeJs
jquery实现轮播图特效
2020/04/12 jQuery
python在ubuntu中的几种安装方法(小结)
2017/12/08 Python
Python request设置HTTPS代理代码解析
2018/02/12 Python
python使用sqlite3时游标使用方法
2018/03/13 Python
python下解压缩zip文件并删除文件的实例
2018/04/24 Python
Python queue队列原理与应用案例分析
2019/09/27 Python
校园歌咏比赛主持词
2014/03/18 职场文书
《月球之谜》教学反思
2014/04/10 职场文书
python爬取企查查企业信息之selenium自动模拟登录企查查
2021/04/08 Python
详解Django的MVT设计模式
2021/04/29 Python
浅析MongoDB之安全认证
2021/06/26 MongoDB