序列化/反序列化的PHP对象的图形化到JSON [英] Serialize/unserialize PHP object-graph to JSON

查看:337
本文介绍了序列化/反序列化的PHP对象的图形化到JSON的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想序列化一个完整的PHP对象的图形化到JSON字符串重新presentation和反序列化回一个相同的PHP对象的图形。

I wanted to serialize a complete PHP object-graph to a JSON string representation, and unserialize it back to an identical PHP object-graph.

下面是我考虑的选项,原因总结他们为什么不为我工作:

Here is a summary of options I considered, and reasons why they don't work for me:


  • 连载()不会做我想做的,因为它使用特定于PHP的格式。我想这是广受大多数语言支持的格式,以及人类可读/可编辑。

  • serialize() doesn't do what I want, because it uses a format specific to PHP. I want a format that is widely supported by most languages, and human-readable/editable.

json_en code()不会做我想做的,因为它只做简单的值和数组,而不是对象。 (实际上,我在我的实现使用此,请参阅下文。)

json_encode() doesn't do what I want, because it only does simple values and arrays, not objects. (I'm actually using this in my implementation, see below.)

var_export()不处理循环引用,并没有做我想做的(见上文)的(注意,我目前的实现不处理循环引用或者 - 看评论及以下澄清这个问题的回答)

var_export() doesn't handle circular references, and doesn't do what I want (see above.) (note that my current implementation does not handle circular references either - see comments and reply below for clarification of this issue.)

塞巴斯蒂安伯格曼的对象冷冻是一个很好的实现,但它不做T我想无论是 - 它使用了很长的表格,并依赖于馅序列化对象与GUID的

Sebastian Bergmann's Object Freezer is a nice implementation, but it doesn't do what I want either - it uses a very long form, and relies on stuffing serialized objects with GUIDs.

序列化不会做我想做的 - 它实际上并不执行序列化,它解析连载()的输出,并产生不同的再presentation,例如: XML,但无法解析重新presentation。 (它也不支持JSON - XML是很长的表格,而不是我想要的)

Serialized doesn't do what I want - it does not actually perform serialization, it parses the output of serialize() and produces a different representation, e.g. XML, but is unable to parse that representation. (it also does not support JSON - XML is very long form, and is not what I want.)

我现在有一个工作实现共享:

I now have a working implementation to share:

https://github.com/mindplay-dk/jsonfreeze

该对象的图形化的JSON-RE presentation看起来是这样的:

The JSON-representation of the object-graph looks like this:

{
    "#type": "Order",
    "orderNo": 123,
    "lines": [{
        "#type": "OrderLine",
        "item": "milk \"fuzz\"",
        "amount": 3,
        "options": null
    }, {
        "#type": "OrderLine",
        "item": "cookies",
        "amount": 7,
        "options": {
            "#type": "#hash",
            "flavor": "chocolate",
            "weight": "1\/2 lb"
        }
    }],
    "paid": true
}

本办法旨在为一个纯粹的树结构汇总工作 - 循环引用是不允许的,也不是同一个对象的多个引用。换言之,这是不通用的像例如连载()反序列化()这对于任何PHP对象的图形。

This approach is designed to work for a pure tree-structure aggregate - circular references are not allowed, nor multiple references to the same objects. In other words, this is not general-purpose like e.g. serialize() and unserialize() which function for any PHP object-graph.

在我的最初的方法我用了一个序列化的形式,基本上是一个基地,0列表对象。列表中(编号0)的第一个目的是序列化对象图的根,任何其他对象存储在它们中找到的顺序

In my initial approach I used a serialized form that was essentially a base-0 list of objects. The first object in the list (number 0) is the root of the serialized object-graph, any other objects are stored in the order they're found.

在当前实现中,JSON重新presentation类似于原始树结构的延伸,这是可能的,从而有可能实际上在JavaScript中对象图的JSON重新presentation工作。唯一的偏差是魔术 #TYPE 属性(prefixed以#与财产的名称prevent碰撞)和 #hash 型,用来区分阵列型哈希值(存储为JSON对象)从普通的阵列型阵列(存储为JSON数组)。

In the current implementation, the JSON representation resembles the original tree-structure to the extend that this is possible, making it possible to actually work with the JSON representation of an object-graph in JavaScript. The only deviation is the magic #type property (prefixed with # to prevent collision with property-names) and the #hash "type", used to distinguish array-type hashes (stored as JSON objects) from regular array-type arrays (stored as JSON arrays).

我要离开这些笔记有关previous版本在这里历史的目的。

循环引用被从未存储每个对象的序列重新presentation内部嵌套对象简单地处理例如 {__ OREF:2} 是一个参考,在对象列表指数 2 对象

Circular references are handled simply by never storing nested objects inside the serialized representation of each object - instead, any object-reference is stored as a JSON-object with the object-index - e.g. {"__oref":2} is a reference to the object with index 2 in the object-list.

我在与我在执行数组引用的一个问题 - 当我的var_dump()的code,恢复对象的数组引用内部,他们被填充,但在某些时候数组被复制和你最终的空复制。我试过把&放大器; 字符无处不在的code,但无论在哪里,我通过引用传递,最终的结果是一个空数组

I'm having a problem with array-references in my implementation - when I var_dump() inside the code that restores references to objects to the array, they are being populated, but at some point the array gets copied, and you end up with the empty copy. I've tried placing & characters everywhere in the code, but regardless of where I pass by reference, the end-result is an empty array.

推荐答案

完成的脚本(上面贴)符合我的precise要求:

The finished script (posted above) meets my precise requirements:


  • 序列化和反序列化的整个集合。

  • Serialize and unserialize an entire aggregate.

有一个JSON重新presentation非常类似原始数据结构。

Have a JSON representation that closely resembles the original data-structure.

不要使用动态生成的密钥或其他数据污染的数据结构。

Do not pollute the data-structure with dynamically generated keys or other data.

它不处理循环引用。如在<一个指出href=\"http://stackoverflow.com/questions/10489876/serialize-unserialize-php-object-graph-to-json-partially-working-solution-need#comment13570677_10489876\">comment上述中有循环引用或多个引用存储到同一个对象没有正确的方式,因为这些都是平等的。认识到这一点,我决定我的对象图必须是一个普通的树,并接受了这种限制是一件好事。

It does not handle circular references. As pointed out in a comment above there is no right way to store circular references or multiple references to the same object, as these are all equal. Realizing this, I decided my object-graph must be a regular tree, and accepted this limitation as "a good thing".

更新:在输出中现在可以使用缩进,换行和空白格式化 - 对我来说,有一个人类可读(和源控制型)再presentation因为它是重要的我目的。 (格式化可以启用或根据需要被禁用。)

update: the ouput can now be formatted with indentation, newlines and whitespace - it was important for me to have a human-readable (and source-control friendly) representation for my purposes. (The formatting can be enabled or disabled as needed.)

这篇关于序列化/反序列化的PHP对象的图形化到JSON的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆