【问题标题】:Symfony Serializer Deserializing XML into Object with childrenSymfony 序列化器将 XML 反序列化为带有子对象的对象
【发布时间】:2019-05-08 13:01:57
【问题描述】:

我有以下 XML:

<CinemaListExport>
    <Cinema>
        ....
        <screens>
            <screen></screen>
            <screen></screen>
        </screens>
    </Cinema>
    <Cinema>
    ....
    </Cinema>
<CinemaListExport>

我正在尝试将其转换为以下对象:

class CinemaList
{
    /**
     * @var Cinema[]
     */
    public $cinema;

    public function __construct()
    {
        $this->cinema = new ArrayCollection();
    }

    public function addCinema(Cinema $cinema)
    {
        $this->cinema[] = $cinema;
    }
class Cinema
{
    fields...

    /**
     * @var Screen[]
     */
    public $screens = [];

使用以下代码:

        $normalizers = [
            new ArrayDenormalizer(),
            new ObjectNormalizer(null, null, null, new ReflectionExtractor())
        ];
        $encoders = [new XmlEncoder()];

        $serializer = new Serializer($normalizers, $encoders);


        $res = $serializer->deserialize($xml, CinemaList::class, 'xml');

无论我做什么,我总是得到以下结果:

class CinemaList#265 (1) {
  public $cinema =>
  class Doctrine\Common\Collections\ArrayCollection#317 (1) {
    private $elements =>
    array(0) {
    }
  }
}

谁能指出我正确的方向?我在这里做错了什么? 我只需要 CinemaList 来包含所有的电影院,而每个 Cinema 来包含它的所有屏幕

【问题讨论】:

    标签: php serialization symfony4


    【解决方案1】:

    好吧,我必须开发您的解决方案并进行一些搜索以了解为什么这个简单的用例不起作用。

    首先,您错过了规范化器ArrayDenormalizer,它是反序列化您的电影和屏幕集合所必需的:

    use Symfony\Component\PropertyInfo\Extractor\ReflectionExtractor;
    use Symfony\Component\Serializer\Encoder\XmlEncoder;
    use Symfony\Component\Serializer\Normalizer\ArrayDenormalizer;
    use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
    use Symfony\Component\Serializer\Serializer;
    
    $objectNormalizer = new ObjectNormalizer(null, null, null, new ReflectionExtractor());
    
    $serializer = new Serializer(
        [new ArrayDenormalizer(), $objectNormalizer], [new XmlEncoder()]
    );
    

    如果没有这个规范化器,数组和集合就会被跳过。

    关于序列化/反序列化还有另外一件事,尤其是使用PropertyAccess 组件的ObjectNormalizer

    如果你想让它工作,你必须同时实现 adderremover 方法。

    很多事情发生在 PropertyAccessor::writeProperty 方法中。我不会解释所有的机制,但很快:如果你有方法 addXXX 和 removeXXX,那么 addXXX 将被优先使用。小心 !如果您只有 addXXX 方法,则不会使用它……我不知道他们为什么这样做,但肯定有充分的理由。 第二个选项是setter。如果它存在(并且您没有 removeXXX 或 addXXX),那么它将用于添加集合中的项目。

    来自here

    我在一个新的 symfony 项目中做了一些成功的测试。如果您仍然遇到问题,我很乐意为您提供帮助。

    【讨论】:

    • 谢谢。我正在查看链接并将尝试一下。不知道为什么这个序列化器需要这么复杂......
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-10-10
    • 2020-05-10
    • 1970-01-01
    • 1970-01-01
    • 2018-07-17
    • 1970-01-01
    相关资源
    最近更新 更多