Php学习之json_decode 遇到的坑详解

本文和大家分享的是php中json_decode遇到的坑,一起来看看吧,希望对大家学习php有所帮助。

场景:某项目客户反馈,输出的结果 JSON 中有个要求为对象的数据字段,在某些情况下返回的是 [] 而不是 {} ;数据由公司其他部门提供,查看原始数据的时候,没有发现任何问题;后来因为要加入某些预处理,在获取到其他部门的 JSON 数据之后进行解码并对某个字段进行处理;然而,在处理完之后再次使用JSON 输出,发现结果已经不是我们想要的了。

原始数据

{

...,

"foo": "",

"bar": {},

...

}

其中 foo 是我要进行处理的字段,处理完成之后再次使用 json_encode($data) 进行 JSON 编码。

编码完成之后的结果却是这样的

{

...,

"foo": "",

"bar": [],

...

}

空对象编程了空数组,而且我并没有处理过字段 bar

通过对模拟数据的实测,发现是因为在对 JSON 进行解码的时候,是这么解的

$data = json_decode($jsonString, true)

问题就出在这里,由于 PHP 自身的特性,在 PHP 中 array 是可以代表强类型语言,如 Java 中的 List和 Map 的。

来看 PHP 中 json_decode() 方法是如何定义的

mixed json_decode ( string $json [, bool $assoc = false [, int $depth = 512 [, int $options = 0 ]]] )

当第二个参数 $assoc 为 true 时,返回的类型是 array ,所以问题就来了,当 JSON 中空对象 {} 和[] 空数组,使用这种方式解码出来的结果表现是一致的;即 array() ;当再次 json_encode() 编码的时候就出现了 {} 变 [] 了。

所以正确的做法是在解码 JSON 的时候 json_decode 不要传递第二个参数;让解码结果是一个对象,然后操作对象的属性,操作完成之后再次编码就不会出现偏差。

这种问题最突出在于强类型语言和弱类型语言的 API 对接上,由于项目的下家是使用 Java 语言,所以导致了 BUG

来源:HFX的BLOG

时间: 2024-10-16 23:19:23

Php学习之json_decode 遇到的坑详解的相关文章

学习笔记——Maven settings.xml 配置详解

文件存放位置 全局配置: ${M2_HOME}/conf/settings.xml 用户配置: ${user.home}/.m2/settings.xml note:用户配置优先于全局配置.${user.home} 和和所有其他系统属性只能在3.0+版本上使用.请注意windows和Linux使用变量的区别. settings.xml详解 声明规范 <?xml version="1.0" encoding="UTF-8"?> <settings x

JavaEE学习之Maven配置文件pom.xml详解(转)

一.引言 (本文转载自:http://blog.csdn.net/longeremmy/article/details/9670619) 使用maven有一些时间了,一直没有好好将pom配置文件每个节点的意义好好了解一番.今天突然想来了解下:pom- project object model 项目对象模型.顾名思义,他是用来描述项目信息的,以及构建方式,依赖等.网上有一篇文章写的很详细,这里就借用一下,以备日后使用. 二.详解 1 <project xmlns="http://maven.

学习笔记——Maven pom.xml配置详解

POM的全称是“ProjectObjectModel(项目对象模型)”. pom.xml详解 声明规范 <projectxmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0http://maven.apach

Spring4.0MVC学习资料,Controller中的方法详解和使用(四)

在以前,mvc的框架,基本上就是struts框架了.但是现在不一样了.springmvc出来了.spring的mvc框架不亚于struts了,springmvc出来了,我们有了更多的选择. Spring MVC属于SpringFrameWork的后续产品,已经融合在Spring Web Flow里面.Spring 框架提供了构建 Web 应用程序的全功能 MVC 模块.使用 Spring 可插入的 MVC 架构,可以选择是使用内置的 Spring Web 框架还可以是 Struts 这样的 We

Spring4.0MVC学习资料,ApplicationContext中的方法详解(三)

做为java开源的一部分,spring框架一直排在老大的位置.Spring4.0 是 Spring 推出的一个重大版本升级,进一步加强了 Spring 作为 Java 领域第一开源平台的地位.Spring4.0 引入了众多 Java 开发者期盼的新特性,如泛型依赖注入.SpEL.校验及格式化框架.Rest风格的 WEB 编程模型等.这些新功能实用性强.易用性高,可大幅降低 JavaEE 开发的难度,同时有效提升应用开发的优雅性.为了方便开发,Spring的ApplicationContext类,

Java8 Lambda表达式深入学习(2) -- InvokeDynamic指令详解

为了更好的支持动态类型语言,Java7通过JSR292给JVM增加了一条新的字节码指令:invokedynamic.之后,JVM上面的一些动态类型语言,比如Groovy(2.0+)和JRuby(1.7.0+)都开始支持invokedynamic.不过让人意外的是,为动态语言量身定制的invokedynamic指令,居然也被用到了Java8的Lambda表达式(JSR335)实现上.本文会对invokedynamic(以下简写做indy)指令做出详细解释. 测试代码 Java7以及更早版本的Jav

JavaFX学习之道:JavaFX API详解之Window,Stage,PopupWindow

stage包中包含 Window, Stage, PopupWindow, Popup, FileChooser, DirectoryChooser, Screen等类. 其中Window类可理解成一个窗体,用于存放Scene,并与用户操作.一般window作为窗体,都用其子类Stage和PopupWindow. 看一下Window作为窗体的顶级类包含的一些共同属性 eventDispatcher setEventDispatcher(EventDispatcher value) focused

linux学习之linux的hostname修改详解《转》

linux的hostname是一个kernel变量,可以通过hostname命令来查看本机的hostname.也可以直接cat /proc/sys/kernel/hostname查看. #hostname #cat /proc/sys/kernel/hostname 上面两种输出结果相同. 修改运行时Linux系统的hostname,即不需要重启系统 hostname命令可以设置系统的hostname #hostname newname newname即要设置的新的hostname,运行后立即生

OpenCV学习C++接口 Mat像素遍历详解

OpenCV学习C++接口 Mat像素遍历详解 原文地址:https://www.cnblogs.com/zhehan54/p/8460602.html