PHP转Go实践:xjson解析神器「开源工具集」
前言
近期会更新一系列开源项目的文章,新的一年会和大家做更多的开源项目,也欢迎大家加入进来。
xutil
今天分享的文章源自于开源项目jinzaigo/xutil的封装。
在封装过程中,劲仔将实现原理以及相关实践思考,写成文章分享出来,从而汇总系列文章集合。
PHP转Go
我和劲仔都是PHP转Go,身边越来越多做PHP的朋友也逐渐在用Go进行重构,重构过程中,会发现php的json解析操作(系列化与反序列化)是真的香,弱类型语言的各种隐式类型转换,很大程度的减低了程序的复杂度。
反观go使用标准库encoding/json,来做json解析就没有那么愉快了(只要数据类型定义不对,就很容易抛error)
JSON解析实践
案例:用go重构的服务,对接的上游还是php服务,这时php接口输出的json串为{"name":"AppleWatchS8","price":"3199"} 。
其中price字段应该得为float类型,但由于php弱类型语言,没有强制约束输出类型的机制,就很容易出现这种输出类型不对的情况,然后到go服务里得怎么处理呢?
标准库encoding/json
package main
import (
"encoding/json"
"fmt"
)
type ProductInfo struct {
Name string `json:"name"`
Price float32 `json:"price"`
}
func main() {
str := "{"name":"AppleWatchS8","price":"3199"}"
data := ProductInfo{}
if err := json.Unmarshal([]byte(str), &data); err != nil {
fmt.Println("error: " + err.Error())
} else {
fmt.Println(data)
}
}
//输出结果
//error: json: cannot unmarshal string into Go struct field ProductInfo.price of type float32
显然,使用go标准库做json解析,是应对不了这种类型不一致的情况的。下面则借助第三方库的能力来做处理
第三方库json-iterator
简单介绍:
执行速度:jsoniter 的 Golang 版本可以比标准库(encoding/json)快 6 倍之多
两个特点:
完全兼容标准库,也就是API用法完全一样,原有逻辑代码不需要改动,只需要替换import包名
提供了一个PHP兼容模式,可以自动转换字符串/数字弱类型问题,可以将空数组[]转换为空结构体(解决PHP中的array输出为[]的问题)。注意,该兼容模式需要手动开启
安装方式:
go get -u github.com/json-iterator/go
具体代码实现:
package main
import (
"fmt"
jsoniter "github.com/json-iterator/go"
"github.com/json-iterator/go/extra"
)
var json = jsoniter.ConfigCompatibleWithStandardLibrary
func init() {
extra.RegisterFuzzyDecoders() //开启PHP兼容模式
}
type ProductInfo struct {
Name string `json:"name"`
Price float32 `json:"price"`
}
func main() {
str := "{"name":"AppleWatchS8","price":"3199"}"
data := ProductInfo{}
if err := json.Unmarshal([]byte(str), &data); err != nil {
fmt.Println("error: " + err.Error())
} else {
fmt.Println(data)
}
}
//输出结果
//{AppleWatchS8 3199}
看输出结果,会发现用了这个库并且开启了PHP兼容模式,json中price字段string类型,就会自动转换为结构体中定义的float32类型。
这样我们在使用price字段处理业务逻辑时,就只需要按float32做处理就行,不用进行类型断言。这个库解决了json解析类型转换问题的同时,也能极大的提高我们开发效率。
收集到开源工具包xutil中
这个第三库用起来如此方便,那肯定是要收录进来的,将替换包名、手动开启PHP兼容模式、还有常用的API方法(系列化与反序列化操作),统一封装进来,简化使用流程。
同时,为了便于后续扩展更多的兼容模式,所以将代码都放在xjson目录下

以上这个思路也适用于大家封装自己内部使用的工具库。
使用示例:
go get -u github.com/jinzaigo/xutil之后,
import github.com/jinzaigo/xutil/xjson,
即可通过xjson.Unmarshal()等方法,进行json解析操作。
示例代码:
package main
import (
"fmt"
"github.com/jinzaigo/xutil/xjson"
)
type ProductInfo struct {
Name string `json:"name"`
Price float32 `json:"price"`
}
func main() {
str := "{"name":"AppleWatchS8","price":"3199"}"
data := ProductInfo{}
if err := xjson.Unmarshal([]byte(str), &data); err != nil {
fmt.Println("error: " + err.Error())
} else {
fmt.Println(data)
}
}
总结
业务系统从php转go,或go对接php服务,都会遇到这个因为数据类型不一致导致json解析错误的共性问题。
使用第三方库json-iterator能很好的解决我们的痛点,并且比标准库执行速度还更快。
收录到开源项目中,更好的帮助到需要的朋友,欢迎使用、star与PR共同建设。
https://github.com/jinzaigo/xutil
PHP转Go实践:xjson解析神器「开源工具集」的更多相关文章
- 「CF319E」Ping-Pong「线段树」「并查集」
题意 规定区间\((a,b)\)到区间\((c,d)\)有边当且仅当\(c<a<d\)或\(c<b<d\). 起初区间集合为空.有\(n\)(\(n\leq 10^5\))次操 ...
- 「LOJ 121」「离线可过」动态图连通性「按时间分治 」「并查集」
题意 你要维护一张\(n\)个点的无向简单图.你被要求执行\(m\)条操作,加入删除一条边及查询两个点是否连通. 0:加入一条边.保证它不存在. 1:删除一条边.保证它存在. 2:查询两个点是否联通. ...
- 看懂「www.google.com」背后的逻辑
在前两篇文章中,我们完整的描述了计算机网络 OSI 五层模型的相关内容.那么,本篇将会从一个实践案例开始,带你从整体上重新认识我们的计算机网络. 我们以访问 Google 为例,当我们在浏览器地址栏中 ...
- WebSocket原理与实践(三)--解析数据帧
WebSocket原理与实践(三)--解析数据帧 1-1 理解数据帧的含义: 在WebSocket协议中,数据是通过帧序列来传输的.为了数据安全原因,客户端必须掩码(mask)它发送到服务器的所有 ...
- 未来科技城 x 奇点云打造「企业数据大脑」,助力1.3万家企业服务
“当前,政府数字化和数字政府建设已成为一种趋势.一种必然,并且有了一条水到渠成式的实现路径.” 上升为国家战略的数字中国建设加速了”智慧政务“的生动实践,杭州未来科技城的「企业数据大脑」就是一个典型. ...
- 「查缺补漏」巩固你的Nginx知识体系
Nginx篇 基本介绍 Nginx是一款轻量级的 Web服务器 / 反向代理服务器 / 电子邮件(IMAP/POP3)代理服务器,主要的优点是: 支持高并发连接,尤其是静态界面,官方测试Nginx能够 ...
- 「编程羽录」上线,程序员必备的这些技能你能get到嘛?
大家好,我是小羽. 好久不见,给大家带来个好消息,小羽的全新专题「编程羽录」系列正式上新,主要是介绍一些关于面试题和经验总结的文章. 会为大家提供一些技术栈之外,程序员还需要的其他方面硬核知识,做到全 ...
- 报名|「OneAPM x DaoCloud」技术公开课:Docker性能监控!
如今,越来越多的公司开始 Docker 了,「三分之二的公司在尝试了 Docker 后最终使用了它」,也就是说 Docker 的转化率达到了 67%,同时转化时长也控制在 60 天内. 既然 Dock ...
- 企业运营对 DevOps 的「傲慢与偏见」
摘要:出于各种原因,并非所有人都信任 DevOps .有些人觉得 DevOps 只不过给开发者改善产品提供了一个途径而已,还有的人觉得 DevOps 是一堆悦耳的空头支票,甚至有人认为 DevOps ...
- Vue+WebSocket+ES6+Canvas 制作「你画我猜」小游戏
Vue+WebSocket+ES6+Canvas 制作「你画我猜」小游戏 转载 来源:jrainlau 链接:https://segmentfault.com/a/1190000005804860 项 ...
随机推荐
- .NET API 接口数据传输加密最佳实践
.NET API 接口数据传输加密最佳实践 我们在做 Api 接口时,相信一定会有接触到要给传输的请求 body 的内容进行加密传输.其目的就是为了防止一些敏感的内容直接被 UI 层查看或篡改. 其实 ...
- 如何免安装使用 Python?推荐 17 个在线的 Python 解释器!
作者:Al Sweigart 译者:豌豆花下猫@Python猫 英文:https://inventwithpython.com/blog/2022/10/30/17-online-python-ide ...
- clip-path属性深入理解与使用
clip-path CSS 属性可以创建一个只有元素的部分区域可以显示的剪切区域.区域内的部分显示,区域外的隐藏. clip-path的属性值可以是以下几种: 1.inset: 将元素剪裁为一个矩形, ...
- Java函数式编程:三、流与函数式编程
本文是Java函数式编程的最后一篇,承接上文: Java函数式编程:一.函数式接口,lambda表达式和方法引用 Java函数式编程:二.高阶函数,闭包,函数组合以及柯里化 前面都是概念和铺垫,主要讲 ...
- 思维分析逻辑 2 DAY
目录 数据分析多元思维模型 微观能力 中观能力 宏观能力 电商平台分析 整体数据 漏斗模型 互联网金融分析 授信模型 了解芝麻信用分结构 数据源的数据变量 数据处理 游戏数据分析 常规指标 商业化指标 ...
- 【云原生 · Kubernetes】KubeVirt热迁移
[云原生 · Kubernetes]KubeVirt热迁移 检查节点和kubevirt状态 启用热迁移 创建虚拟机 在虚拟机上启动一个服务 迁移虚拟机 热迁移是KubeVirt支持的一个常见虚拟化特性 ...
- Xamarin.Android带参数返回上一级界面
在ActivityA跳转到ActivityB后.activityB返回到ActivityA并带参数返回 首先再activitya中跳转到b var intent = new Intent(this, ...
- Axios +Vue + themeleay
1.pom.xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId& ...
- 解决linux vlc设置中文问题
解决方法 sudo apt install vlc-l10n
- Vue 打包报错UnhandledPromiseRejectionWarning: postcss-svgo: Error in parsing SVG
解决方案 检查下自己最新写的css 或者最新引入的样式库,把里面的base64的url替换成双引号形式的 PS:我这报错是因为引入的weui.min.css里面的loading样式的`backgrou ...