经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » JS/JS库/框架 » JSON » 查看文章
PHP转Go实践:xjson解析神器「开源工具集」
来源:cnblogs  作者:王中阳Go1  时间:2023/1/28 8:43:51  对本文有异议

前言

近期会更新一系列开源项目的文章,新的一年会和大家做更多的开源项目,也欢迎大家加入进来。

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

  1. package main
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. )
  6. type ProductInfo struct {
  7. Name string `json:"name"`
  8. Price float32 `json:"price"`
  9. }
  10. func main() {
  11. str := "{"name":"AppleWatchS8","price":"3199"}"
  12. data := ProductInfo{}
  13. if err := json.Unmarshal([]byte(str), &data); err != nil {
  14. fmt.Println("error: " + err.Error())
  15. } else {
  16. fmt.Println(data)
  17. }
  18. }
  19. //输出结果
  20. //error: json: cannot unmarshal string into Go struct field ProductInfo.price of type float32

显然,使用go标准库做json解析,是应对不了这种类型不一致的情况的。下面则借助第三方库的能力来做处理

第三方库json-iterator

简单介绍:

执行速度:jsoniter 的 Golang 版本可以比标准库(encoding/json)快 6 倍之多

两个特点:

  1. 完全兼容标准库,也就是API用法完全一样,原有逻辑代码不需要改动,只需要替换import包名

  2. 提供了一个PHP兼容模式,可以自动转换字符串/数字弱类型问题,可以将空数组[]转换为空结构体(解决PHP中的array输出为[]的问题)。注意,该兼容模式需要手动开启

安装方式:

  1. go get -u github.com/json-iterator/go

具体代码实现:

  1. package main
  2. import (
  3. "fmt"
  4. jsoniter "github.com/json-iterator/go"
  5. "github.com/json-iterator/go/extra"
  6. )
  7. var json = jsoniter.ConfigCompatibleWithStandardLibrary
  8. func init() {
  9. extra.RegisterFuzzyDecoders() //开启PHP兼容模式
  10. }
  11. type ProductInfo struct {
  12. Name string `json:"name"`
  13. Price float32 `json:"price"`
  14. }
  15. func main() {
  16. str := "{"name":"AppleWatchS8","price":"3199"}"
  17. data := ProductInfo{}
  18. if err := json.Unmarshal([]byte(str), &data); err != nil {
  19. fmt.Println("error: " + err.Error())
  20. } else {
  21. fmt.Println(data)
  22. }
  23. }
  24. //输出结果
  25. //{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解析操作。

示例代码:

  1. package main
  2. import (
  3. "fmt"
  4. "github.com/jinzaigo/xutil/xjson"
  5. )
  6. type ProductInfo struct {
  7. Name string `json:"name"`
  8. Price float32 `json:"price"`
  9. }
  10. func main() {
  11. str := "{"name":"AppleWatchS8","price":"3199"}"
  12. data := ProductInfo{}
  13. if err := xjson.Unmarshal([]byte(str), &data); err != nil {
  14. fmt.Println("error: " + err.Error())
  15. } else {
  16. fmt.Println(data)
  17. }
  18. }

总结

业务系统从php转go,或go对接php服务,都会遇到这个因为数据类型不一致导致json解析错误的共性问题。

使用第三方库json-iterator能很好的解决我们的痛点,并且比标准库执行速度还更快。

收录到开源项目中,更好的帮助到需要的朋友,欢迎使用、star与PR共同建设。

https://github.com/jinzaigo/xutil

原文链接:https://www.cnblogs.com/wangzhongyang/p/17069630.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号