PHP中遇到BOM、<feff>编码导致json_decode函数无法解析问题

昨天同事遇到一个奇怪的问题,就是以下代码,无法通过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的编辑器修改代码,容易引发一些问题。

(0)

相关推荐

  • php json_encode与json_decode详解及实例

    一.json_encode() 该函数主要用来将数组和对象,转换为json格式.先看一个数组转换的例子: $arr = array ('a'=>1,'b'=>2,'c'=>3,'d'=>4,'e'=>5); echo json_encode($arr); 结果为 {"a":1,"b":2,"c":3,"d":4,"e":5} 再看一个对象转换的例子: $obj->body

  • 使用PHP json_decode可能遇到的坑与解决方法

    前言 最近在做网站 的时候用到了json_decode函数,发现了一个问题,现在总结分享出来供大家参考学习,话不多说了,来一起看看详细的介绍吧. 场景: 某项目客户反馈,输出的结果 JSON 中有个要求为对象的数据字段,在某些情况下返回的是 [] 而不是 {}:数据由公司其他部门提供,查看原始数据的时候,没有发现任何问题:后来因为要加入某些预处理,在获取到其他部门的 JSON 数据之后进行解码并对某个字段进行处理:然而,在处理完之后再次使用 JSON 输出,发现结果已经不是我们想要的了. 原始数

  • Javascript生成json的函数代码(可以用php的json_decode解码)

    但是有个问题 虽然JS解码JSON非常方便,但是编码似乎没有什么好办法- 本着能懒即懒,不能懒也尽量懒的原则,古狗了一下 还真让我发现了 PHP里直接用json_decode就可以解码,用起来相当方便 复制代码 代码如下: function json_encode_js(aaa){ function je(str){ var a=[],i=0; var pcs="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"

  • php中json_decode()和json_encode()的使用方法

    1.json_decode() json_decode (PHP 5 >= 5.2.0, PECL json >= 1.2.0) json_decode - 对 JSON 格式的字符串进行编码 说明 mixed json_decode ( string $json [, bool $assoc ] ) 接受一个 JSON 格式的字符串并且把它转换为 PHP 变量 参数 json 待解码的 json string 格式的字符串. assoc 当该参数为 TRUE 时,将返回 array 而非 o

  • 关于php中的json_encode()和json_decode()函数的一些说明

    一,json语法( php中的json_decode($json)中的$json要符合json语法格式 ) ① JSON可以表示三种类型的值 1,简单值.包括整型,字符串型,布尔值和null.例如:5,"hello world",true,null都是有效的JSON数据.其中JSON字符串必须使用双引号(单引号会导致语法错误). 2,对象.如,{"name":"tony","age":15}.说明①要求属性必须用双引号(不加或

  • PHP实现json_decode不转义中文的方法

    本文实例讲述了PHP实现json_decode不转义中文的方法.分享给大家供大家参考,具体如下: 默认情况下PHP的 json_decode 方法会把特殊字符进行转义,还会把中文转为Unicode编码形式. 这使得数据库查看文本变得很麻烦.所以我们需要限制对于中文的转义. 对于PHP5.4+版本,json_decode函数第二个参数,可以用来限制转义范围. 要限制中文,使用JSON_UNESCAPED_UNICODE参数. json_encode($a, JSON_UNESCAPED_UNICO

  • PHP json_decode函数详细解析

    一.函数简介1.此函数有四个参数,一般在使用时会用到前两个,具体的参数可以看手册. 2.第一个参数是json格式的字符串,第二个参数是boolean值(false转化成对象,true转化成数组,默认false),如果转化失败返回null. 二.遇到的问题在项目中调用了java写的一个web服务,返回的数据是"{'stauts':'1','message':'充值成功'}". 程序接到后用json_decode把结果转化成数组,但转化的结果是null,太奇怪了. 看了一下手册,在手册中发

  • 浅析php中json_encode()和json_decode()

    json_encode() 该函数主要用来将数组和对象,转换为json格式. 复制代码 代码如下: $arr = array ('a'=>'a','b'=>'b','c'='c','d'=>'d','e'='e');echo json_encode($arr); 输出结果: json只接受utf-8编码的字符,json_encode()的参数必须是utf-8编码. 复制代码 代码如下: class person{    public $name;    public $age;    p

  • php5.2以下版本无json_decode函数的解决方法

    今天写代码的时候,需要用到json_decode函数,发现php5.2以前的版本没有集成这个函数,不过我们可以通过自定义函数实现. 复制代码 代码如下: function json_decode2($json){$comment = false;$out = '$x='; for ($i=0; $i<strlen($json); $i++){if (!$comment){if (($json[$i] == '{') || ($json[$i] == '[')) $out .= ' array('

  • PHP中遇到BOM、<feff>编码导致json_decode函数无法解析问题

    昨天同事遇到一个奇怪的问题,就是以下代码,无法通过JSON校验,也无法通过PHP的json_decode函数解析. 复制代码 代码如下: [     {         "title": "",         "pinyin": ""     } ] 可能聪明的你已经猜到其中包含有不看见的特殊字符,在vim下查看: 复制代码 代码如下: [     {         <feff>"title&quo

  • WordPress中用于获取搜索表单的PHP函数使用解析

    get_search_form 函数在 WordPress 中是用来提取预设的搜索表单或者默认的搜索表单的.因为官方这个函数没有中文的,所以我就简单写了一下. 描述 get_search_form 函数在 WordPress 中是用来提取自定义搜索表单或者默认的搜索表单的. 显示自定义表单还是显示默认表单,完全取决于您的主题中是否有search.php文件, 如果有该文件,则自动调用该文件,如果没有则显示默认的搜索表单. 使用 <?php get_search_form($echo = true

  • WordPress开发中用于获取近期文章的PHP函数使用解析

    wp_get_recent_posts 函数在 WordPress 中是一个可以获取近期文章数组的函数,相较于其他的文章获取方式, wp_get_recent_posts 返回的将是一个数组而不是对象,所以在使用中对于一些新手或者是懒人,可能会更方便一些,下面我们就实例讲解一下这个函数. 描述 wp_get_recent_posts 英文解释很短,就不贴了, 中文大概意思是:获取最新文章的函数. 实际上这是一个 get_posts函数的再使用. 描述的再好也木用,下面看使用. 使用/用法 <?p

  • WordPress中用于检索模版的相关PHP函数使用解析

    locate_template() 用来检索存在的优先级最高的模板文件,还能直接加载模板文件. locate_template() 函数检索时,如果有子主题则优先使用子主题的模板,没有再继续检索父主题. 用法 locate_template( $template_names, $load, $require_once ); 参数 $template_names (数组)(必须)要引入的模板文件名(需要扩展名),会根据数组逐个匹配文件是否存在,越前边的优先级越高. 默认值:None $load (

  • JS中的BOM应用

    我们曾经讲过JS由三部分组成,其中一个部分就是BOM,用于对浏览器进行操作.这节课我们主要就来介绍BOM. BOM基础 我们先来看一个BOM的最基础功能:打开.关闭窗口: <html> <head> <meta charset="utf-8"> <title>无标题文档</title> </head> <body> <input type="button" value=&quo

  • Web 开发中遇到的UTF-8编码的问题总结第1/2页

    主要有五个方面: 一..HTML页面转UTF-8编码问题 二.PHP页面转UTF-8编码问题 三.MYSQL数据库使用UTF-8编码的问题 四.JS相关的UTF-8编码问题 五.FLASH相关的UTF-8编码问题 一.HTML页面转UTF-8编码问题 1.在<head>后,<title>前加入一行: <meta http-equiv='Content-Type' content='text/html; charset=utf-8' /> 顺序不能错,一定要在<ti

  • gearman中worker常驻后台,导致MySQL server has gone away的解决方法

    本文实例讲述了gearman中worker常驻后台,导致MySQL server has gone away的解决方法.分享给大家供大家参考,具体如下: 产生这个原因主要有如下几点: 1.mysql服务宕机了 2.长时间没有操作,超过了wait_timeout的设置,mysql自动断开 3.mysql请求链接被主动kill 4.发送的请求或返回结果过大,可设置max_allowed_packet的值 5.程序中你都是通过单例来操作数据库,如果两个操作时间超过wait_timeout. 为了演示的

  • redis中的数据结构和编码详解

    redis中的数据结构和编码:     背景: 1>redis在内部使用redisObject结构体来定义存储的值对象. 2>每种类型都有至少两种内部编码,Redis会根据当前值的类型和长度来决定使用哪种编码实现. 3>编码类型转换在Redis写入数据时自动完成,这个转换过程是不可逆的,转换规则只能从小内存编码向大内存编码转换.     源码: 值对象redisObject: typedef struct redisObject {                 unsigned ty

随机推荐