比如
{ "a": "b", "c": "d", }
需要转化为类:
class A { public $a; public $b; }
我想到的方案如下:
class A { public $a; public $b; const props = [ 'a', 'b' ];
但是这样一来,信息就比较冗余了。
class A { const props = [ 'a', 'b' ]; }
$a 和$b 动态添加给 this。
但是显然,失去了 IDE、静态代码分析工具的支持。
目前我觉得 Go 中的,json.Marshal, json.Unmarshal 还是比较方便的,但是看起来不太适合 PHP ?
不好意思,之前的例子确实太简单了。
比如json:
{ "action": "set", "node": { "key": "/testset", "value": "setvalue", "modifiedIndex": 19, "createdIndex": 19 } }
要转换成类:
<?php class Node { /** @var string */ public $key; /** @var string */ public $value; /** @var int */ public $modifiedIndex; /** @var int */ public $createdIndex; } class Response { /** @var string */ public $action; /** @var Node */ public $node; }
当然,stdclass和array也可以,但是我输入$response->node->
,IDE不会补全啊,而且这种对静态代码分析也不友好啊。
1 akrf 2017-07-25 01:23:12 +08:00 via Android 老太婆,你还记不记得有一招从天而降的掌法? |
![]() | 2 oh 2017-07-25 01:26:05 +08:00 |
![]() | 3 imxieke 2017-07-25 01:26:50 +08:00 via Android 没太整明白帖子意思 不过转成数组的话可以 先将 json 转换成数组 然后用 foreach 关注 等待大佬解答 |
![]() | 6 RobberPhex OP json_decode 是 str 到 array,这个根本不是问题的重点。 str 到某个特定的类的转换呢? json 中的 key 对应到 object 中的属性,有存在且为原生类型、存在且是另外一个类型(即嵌套)、不存在该字段。这三种情况如何用比较少的代码来处理。 |
![]() | 7 RobberPhex OP Go 中,可以通过类的属性标签来指示如何从 json 中反序列化出来。php 好像没法添加? |
8 feiyuanqiu 2017-07-25 01:56:44 +08:00 via Android … json_decode 转 json 对象,默认就是转成 stdClass 对象 至于你的要求,你这个 json 字符串又没有带类型信息,php 怎么可能知道要转成哪个类型?别什么问题都赖语言,go 在 unmarshal 的时候也要求你把要转换的类型传进去它才知道该转成什么的 想实现你的需求,要么别用 json 用序列化;要么自己定义一个类似于 go 的 Marshalable 接口,直接继承 JsonSerializable 接口,自己实现一个通用的 unmarshal 方法,将 json 解析出来的数据初始化到具体对象 |
9 akrf 2017-07-25 02:21:03 +08:00 via Android @RobberPhex 第一句话就错了。慢慢学习吧… |
![]() | 10 cxbig 2017-07-25 05:53:05 +08:00 从来就不会用也不期待这样开放性的转换,一定是先定义好 class 和其中的 attribute 和 method,再把数据丢进去处理。 |
11 syncher 2017-07-25 07:48:56 +08:00 |
![]() | 12 torbrowserbridge 2017-07-25 08:05:30 +08:00 楼主你连主题中的第一个 json 都没写对(多了一个结尾的逗号) |
13 jhdxr 2017-07-25 09:01:49 +08:00 没人发现 LZ 的 json 是 {"a":"b", "c": "d"},但类的两个属性却是$a 和$b 么。。。谁能告诉我这个转换规则是什么? |
![]() | 15 eoo 2017-07-25 09:06:33 +08:00 via Android json_decode 不就是对象了吗? |
![]() | 16 Tokin 2017-07-25 09:11:45 +08:00 好奇,json_decode(jsonStr)不是对象吗? json_decode(jsonStr,true)才是数组不是吗?我去试试- - |
![]() | 17 Tokin 2017-07-25 09:25:14 +08:00 ![]() 感觉没什么问题,直接 json_decode 很正确啊 |
![]() | 18 sagaxu 2017-07-25 09:39:38 +08:00 via Android 自己实现吧,phper 一般不这么玩,他们用 stdClass 和 array |
![]() | 19 xzem 2017-07-25 09:41:04 +08:00 via Android phper 表示这种情况不用 json_decode 自己瞎折腾啥啊。 我还觉得强类型语言的 json 反序列化难受呢。 |
![]() | 20 Tokin 2017-07-25 09:42:12 +08:00 @RobberPhex json_decode 并不是 str 到 array。。。 |
![]() | 22 zhongkouwei 2017-07-25 09:48:19 +08:00 摘一段文档: mixed json_decode ( string $json [, bool $assoc = false [, int $depth = 512 [, int $optiOns= 0 ]]] ) 接受一个 JSON 编码的字符串并且把它转换为 PHP 变量。 当 assoc 参数为 TRUE 时,将返回 array 而非 object。 |
![]() | 24 vus520 2017-07-25 09:55:42 +08:00 java 和 go 过来的,一来就开始写映射,php 里不需要啊老铁,json_decode 就够了,没错,省了 1 个小时的 coding。 |
![]() | 25 jarlyyn 2017-07-25 10:22:05 +08:00 一堆强答的。 曾经也想过这个问题,由于 php 没有类型,没有 go 那样的接口,所以很难实现 go 那么爽的 json 转换。 当然,有一些框架做过一些工作,能起到类似的作用。 如 yii 框架 1.x 为例。 首先 yii 实现了一个 CComponent 的基础组建。 所以所有 yii 的类都有可以用 yii::createCpmponent 方法初始化数组为你想要的类。 这是第一步。 然后,Yii 的数据库和表单的基类都是 CForm CForm 可以制定每个字段的验证规则 然后通过 setAttriutes 方法,将一个数组的值制定给一个 CForm 类。 最后,我的选择呢,小项目调接口为主的还是走 go,简单多了。 |
![]() | 26 RobberPhex OP |
![]() | 27 gouchaoer 2017-07-25 10:37:33 +08:00 我个人觉得 php 的 json 操作真的是最简单的了,就用 array 搞定一切 |
![]() | 28 bombless 2017-07-25 10:39:55 +08:00 v2 的 php 水平不太行,哈哈 以前瞎逛 StackOverflow 的时候看过别人的解决方案,比较 hack,大意就是得到 stdClass 实例后 serialize() ,之后去修改那串编码,后面再 unserialize() 回来。当然这样做的前提是你已经知道要转成什么类型了。 |
![]() | 29 jarlyyn 2017-07-25 10:47:22 +08:00 |
![]() | 31 yzmm 2017-07-25 13:22:59 +08:00 php 的 json 库支持得不够友好,没法直接序列化一个 class 也没法直接反序列化 |
32 Balthild 2017-07-25 13:46:58 +08:00 好多人不审题就答…… |
![]() | 33 voocel 2017-07-25 14:26:41 +08:00 我来强答一波... |
![]() | 34 voocel 2017-07-25 14:27:07 +08:00 为什么叫你老太婆 |
![]() | 35 POPOEVER 2017-07-25 14:35:24 +08:00 类不行的,#31 说得对的,你得自己扩展,或者看看这个 https://github.com/cweiske/jsonmapper |
36 chahualao 2017-07-25 17:16:21 +08:00 我第一眼看标题,啊,这不 json_decode 不就完了吗? 然后楼主思路,啊?我是不是理解错了?啊,难道我学的东西有问题?啊,我要去试一下。。。。。。 |
37 erming 2017-07-25 17:51:52 +08:00 @RobberPhex json_decode 是 str 到 array ? 查下手测吧,第二个参数什么意思 |
![]() | 38 junbguistar 2017-07-25 18:26:47 +08:00 看了评论才 get 到楼主的 point |
![]() | 39 ditel 2017-07-25 19:52:18 +08:00 via Android 先转数组,再组合成想要的,再转回 json,再转成 stdclass,估计可以,自己 hack |
40 cnwggu 2017-07-26 13:30:45 +08:00 同意 #35 楼,jsonmapper 可以一试 |
![]() | 41 opengg 2017-07-26 16:01:11 +08:00 json 没有类型信息,瞎搞啥呀。 需要类型的话,你改用 wsdl 吧,舒服了。 |