PHP:对象数组-序列化与json_encode-替换


PHP: array of objects - serialize vs json_encode - alternatives?

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

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

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

var_exporteval结合使用效果良好,但速度大约是其他方法的3倍,并且占用了更多的内存。

现在我的问题是:

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

更新

我开始相信我的数组数据一定有什么奇怪的地方,因为使用msgpack_serialize(php扩展,serialize的替代),我会得到同样的错误(但奇怪的是而不是相同的对象生成错误!)。

更新2

找到了一个解决方案:我现在不在整个阵列上执行serialize,而是在每个对象上执行,先是serialize,然后是base64_encode,然后将每个序列化的对象作为单独的一行存储在文本文件中。通过这种方式,我可以生成整个对象数组,然后使用file()unserializebase64_decode迭代每个对象:不再有错误!

通过serialize/unserialize函数连接了两个神奇的方法。

__sleep()

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

有了睡眠,你可以更好地控制序列化操作——你可以传递可以序列化的变量,并在重新序列化之前清理资源。

当调用unserialize时,应提及其他函数

__唤醒()

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

关于json_encode()

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

这取决于你选择什么,但对于具有数据库连接等的更高级的类,我建议serialize()