PHP json解析库,golang - 利用json-iterator库兼容解析PHP JSON | 鱼儿的博客

很多Gopher是从PHP转过来的,在重构代码到GO的过程中一定会遇到JSON解析的问题。

PHP是弱类型,所以经常把数字10写成字符串”10″,导致一个表达年龄的JSON变成了这样:

Shell

{

"age": "10"

}

1

2

3

{

"age":"10"

}

标准库json

golang标准库的json并不能兼容这种情况下的解析,因此如果我们的struct企图使用int来反射这个字段,将会导致decode失败:

Go

package main

import (

"encoding/json"

"fmt"

)

type StdStruct struct {

Age int `json:"age"`

}

func main() {

s := "{\"age\": \"10\"}"

d := &StdStruct{}

if err := json.Unmarshal([]byte(s), d); err != nil {

fmt.Println(err)

} else {

fmt.Println(d.Age)

}

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

packagemain

import(

"encoding/json"

"fmt"

)

typeStdStructstruct{

Ageint`json:"age"`

}

funcmain(){

s:="{\"age\": \"10\"}"

d:=&StdStruct{}

iferr:=json.Unmarshal([]byte(s),d);err!=nil{

fmt.Println(err)

}else{

fmt.Println(d.Age)

}

}

运行报错:

json: cannot unmarshal string into Go struct field StdStruct.age of type int

第三方json-iterator库

这个库有2个特点:

完全兼容json标准库,也就是API用法完全一样,原有代码不需要改动。

提供了一个兼容模式,可以自动转换字符串/数字弱类型问题,可以转换[]与{}弱类型问题(PHP中的array问题)。

它的基本用法如下:

Go

package main

import (

"fmt"

jsoniter "github.com/json-iterator/go"

)

var json = jsoniter.ConfigCompatibleWithStandardLibrary

type StdStruct struct {

Age int `json:"age"`

}

func main() {

s := "{\"age\": \"10\"}"

d := &StdStruct{}

if err := json.Unmarshal([]byte(s), d); err != nil {

fmt.Println(err)

} else {

fmt.Println(d.Age)

}

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

packagemain

import(

"fmt"

jsoniter"github.com/json-iterator/go"

)

varjson=jsoniter.ConfigCompatibleWithStandardLibrary

typeStdStructstruct{

Ageint`json:"age"`

}

funcmain(){

s:="{\"age\": \"10\"}"

d:=&StdStruct{}

iferr:=json.Unmarshal([]byte(s),d);err!=nil{

fmt.Println(err)

}else{

fmt.Println(d.Age)

}

}

删除原先的import encoding/json标准库,引入jsoniter库。

创建一个变量叫做json,取值自jsoniter.ConfigCompatibleWithStandardLibrary。

其他业务代码不需要调整,即可继续按照原先的json.Unmarshal等用法运行。

但是这样的代码仍旧会报错:

main.StdStruct.Age: readUint64: unexpected character: �, error found in #9 byte of …|{“age”: “10”}|…, bigger context …|{“age”: “10”}|…

原因是我们需要手动开启PHP的兼容模式,否则默认只是兼容了json标准库,因此可以运行的代码如下:

Go

package main

import (

"fmt"

jsoniter "github.com/json-iterator/go"

"github.com/json-iterator/go/extra"

)

var json = jsoniter.ConfigCompatibleWithStandardLibrary

func init() {

// RegisterFuzzyDecoders decode input from PHP with tolerance.

// It will handle string/number auto conversation, and treat empty [] as empty struct.

extra.RegisterFuzzyDecoders()

}

type StdStruct struct {

Age int `json:"age"`

}

func main() {

s := "{\"age\": \"10\"}"

d := &StdStruct{}

if err := json.Unmarshal([]byte(s), d); err != nil {

fmt.Println(err)

} else {

fmt.Println(d.Age)

}

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

packagemain

import(

"fmt"

jsoniter"github.com/json-iterator/go"

"github.com/json-iterator/go/extra"

)

varjson=jsoniter.ConfigCompatibleWithStandardLibrary

funcinit(){

// RegisterFuzzyDecoders decode input from PHP with tolerance.

//  It will handle string/number auto conversation, and treat empty [] as empty struct.

extra.RegisterFuzzyDecoders()

}

typeStdStructstruct{

Ageint`json:"age"`

}

funcmain(){

s:="{\"age\": \"10\"}"

d:=&StdStruct{}

iferr:=json.Unmarshal([]byte(s),d);err!=nil{

fmt.Println(err)

}else{

fmt.Println(d.Age)

}

}

可以得到打印输出:

10

后记:我们只需要在main文件里通过init开启1次PHP兼容模式即可,后续引入的模块不需要重复开启。

如果文章帮助了你,请帮我点击1次谷歌广告,或者微信赞助1元钱,感谢!

c68972f84f7c4f47f59a1f69f0608e10.png

知识星球有更多干货内容,对我认可欢迎加入:

6c9a48ad74e3675cedd6ca98c1fd0a1f.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值