6

在 PHP 中,我很难在大量对象(100000 多个对象)上使用serialize/ 。unserialize这些对象可以有很多不同的类型,但都是基类的后代。

不知何故,当我unserialize在对象数组上使用时,大约 0,001% 的对象生成错误!而是生成了一个完全不同的对象。这不是随机发生的,而是每次都使用相同的对象。但是如果我改变数组的顺序,它会发生在不同的对象上,所以这对我来说就像一个错误。

我切换到json_encode/ json_decode,但发现它总是stdClass用作对象的类。我通过将每个对象的类名包含为一个属性来解决这个问题,然后使用这个属性构造一个新对象,但是这个解决方案不是很优雅。

使用var_exportwitheval效果很好,但比其他方法慢 3 倍,并且使用更多内存。

现在我的问题是:

  • 什么可能导致创建的错误/错误对象 unserialize
  • 有没有更好的方法来使用json_decode对象数组,以便类以某种方式自动存储在 json 中?
  • 是否还有其他方法可以在 PHP 中读取/写入大量对象?

更新

我开始相信我的数组数据一定有一些奇怪的地方,因为使用msgpack_serialize(php extension, alternative to serialize) 我得到了同样的错误(但奇怪的是,生成的对象不是错误的!)

更新 2

找到了一个解决方案:serialize我不是在整个数组上做,而是在每个对象上做,先是serialize然后base64_encode,然后我将每个序列化的对象作为单独的行存储在文本文件中。这样我就可以生成整个对象数组,然后使用file()withunserialize和迭代每个对象base64_decode :没有更多错误!

4

1 回答 1

4

使用序列化/反序列化函数连接了 2 个魔术方法。

__睡觉()

serialize() 检查你的类是否有一个名为 __sleep() 的函数。如果是这样,则该函数在任何序列化之前执行。它可以清理对象,并且应该返回一个数组,其中包含应该序列化的该对象的所有变量的名称。如果该方法没有返回任何内容,则序列化 NULL 并发出 E_NOTICE。

通过睡眠,您可以更好地控制序列化操作,您可以传递可以序列化的变量并在序列化之前清理资源。

当调用反序列化时,应该提到另一个函数

__醒来()

__wakeup() 的预期用途是重新建立在序列化期间可能丢失的任何数据库连接并执行其他重新初始化任务。

关于 json_encode()

  1. 它没有神奇的方法 __wakeup, __sleep 所以你的控制权更少
  2. 它不序列化私有属性
  3. 对象始终存储为 stdClass
  4. Json_encode 比序列化快

这取决于您选择什么,但对于具有 db 连接等的更高级的类。我建议 serialize()

于 2013-07-05T13:06:09.950 回答