如何对一个SimpleXML对象进行序列化/反序列化?

14

我看过一些处理序列化SPL对象的创新方案,但我正在寻找更多选项或详细说明。我将嵌套的序列化对象 - 其中一个是SimpleXML - 存储在数据库中,只能在以后反序列化。这显然会引起一些问题。

$s = new SimpleXmlElement('<foo>bar</foo>');
$ss = serialize($s);
$su = unserialize($ss);
// Warning: unserialize() [function.unserialize]: Node no longer exists...

有没有人对处理序列化SPL对象的高可靠性方法有深入了解? __sleep()/__wakeup()重写?转换为stdClass?转换为字符串,然后序列化?

感谢任何帮助。

[编辑:这些XML模式的范围和变化太多,无法使用ORM进行映射。它们在状态过程中是任意有效负载,在restful API中触发。]

3个回答

36

虽然涉及适当性的问题,但你可以像这样将它转换回XML:

$xml = $simpleXmlElem->asXML();

然后,当你从数据库中获取它时:

$simpleXmlElem = simplexml_load_string($xml);

关于是否适合仅序列化大块的XML,放入数据库中可以去除使用关系系统的许多优势,但您确实可以获得适应任意工作负载的优势。如果一些字段是通用的,并且/或者您从规范化它们中获得了好处(例如,您想根据这些字段进行选择),请将它们移动到规范化的列中。


4
我认为更重要的问题是为什么PHP不自动执行此操作?在PHP中对XML对象进行序列化/反序列化是否会受到严重影响? - devios1

3
更加清晰和面向对象化。
namespace MyApp;
class SimpleXMLElement extends \SimpleXMLElement
{
    public function arrayToXml($array = array())
    {
        array_walk_recursive($array, array(&$this, 'addChildInverted'));
        return $this;
    }

    public function addChildInverted($name ,$value)
    {
        parent::addChild($value,$name);
    }

}

并且调用
  $xml = new \MyApp\SimpleXMLElement('<resultado/>');
  echo $xml->arrayToXml($app->getReturnedValue())->asXML();

1

仅呈现和存储 XML 是否是将表示 XML 结构的任何对象序列化的最佳方式?

您尝试使用序列化数据做什么可能会阻止这个方法?

编辑:

此外,

我在数据库中存储了嵌套的序列化对象[...],只有在以后才能取消序列化

为什么要在数据库中存储 PHP 序列化数据?有许多更好的方法来存储对象在数据库中。


1
你为什么要将PHP序列化数据存储在数据库中?为了存储相当大的动态进程的状态。“难道渲染和存储XML不是序列化表示XML结构的任何对象的最佳方法吗?”可能是的。这就是我提出的问题。 - allnightgrocery
有很多更好的方法来存储对象。您想详细说明一下这一点吗? - allnightgrocery
1
当然。尝试将对象中的每个属性映射到表中的列。如果该属性本身是一个对象,则需要将该对象存储在另一个表中,并可以使用外键在父表中引用它。这通常称为“对象关系映射”,可能会变得有点复杂。当然,如果您正在使用键值或文档数据库,则情况会有所不同... - Charles
当然,ORM。我们有一个完整的ORM模式用于核心元素,但更复杂的元素是这些过程(n长度和100%动态)。几乎不可能将ORM模式范围限定在处理大量对象,变化和状态更改方面。尽管如此,这对于我们的核心模型绝对至关重要。看到坚实的结构进入设计讨论总是很好的。 - allnightgrocery
如果数据结构良好,或许像文档数据库这样的存储方式会比将其序列化为 blob 并放入表格中更好。 - Charles

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接