如何在具有多个子实例的嵌套对象上使用Symfony Serializer?

时间:2018-01-24 16:08:07

标签: symfony serializer

使用下面的简单示例,如何更新它以处理多个联系号码?

<?php
/**
* Symfony Serializer experiment  
*/
require $_SERVER['DOCUMENT_ROOT'].'/libraries/symfony/vendor/autoload.php';

use Symfony\Component\Serializer\Serializer;
use Symfony\Component\Serializer\Encoder\XmlEncoder;
use Symfony\Component\Serializer\Encoder\JsonEncoder;
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
use Symfony\Component\Serializer\Normalizer\ArrayDenormalizer;

class Contact
{
    private $name;
    private $number;

    // Getters
    public function getName()
    {
        return $this->name;
    }
    public function getNumber()
    {
        return $this->number;
    }    
    // Setters
    public function setName($name)
    {
        $this->name = $name;
    }
    public function setNumber($number)
    {
        $this->number = $number;
    }    
} 

$data = <<<EOF
<contact>
    <name>foo</name>
    <number>02378415326</number>        
</contact>
EOF;

// The default Root tag for the XmlEncode is <response>. Not what we want so let's change it to <Contact>
$xmlEncoder = new XmlEncoder();
$xmlEncoder->setRootNodeName('Contact');                

$encoders = array($xmlEncoder, new JsonEncoder());

$normalizers = array(new ObjectNormalizer(), new ArrayDenormalizer());

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

//$jsonContent = $serializer->serialize($searchId, 'json');

$contact = $serializer->deserialize($data, Contact::class, 'xml');

$xmlContent = $serializer->serialize($contact, 'xml');

echo "<pre lang=xml>";
echo htmlentities($xmlContent);
echo "</pre>";     
?>

我想知道的是如何对我的类进行编码,以便能够对以下xml进行序列化/反序列化,其中可以有任意数量的数字。?

$data = <<<EOF
<contact>
    <name>foo</name>
    <numbers>
        <number>02378415326</number>
        ...
    </numbers>        
</contact>
EOF; 

我猜测我首先要改变属性中的数字联系到Numbers并使其成为Number类型的数组?我需要一个单独的数字和数字类。由于Numbers是一个集合,我如何以我可以创建Number对象的方式实现它,然后添加到Numbers类,然后添加到Contacts,或直接添加到Contact中的Numbers,以便序列化/反序列化可以处理原生?我读到Serialize可以理解加法器,删除器和issers以及setter和getter,但是没有找到如何使用加法器的示例,看起来它在我的情况下可能有用。

2 个答案:

答案 0 :(得分:0)

如果您有多个联系号码,则需要具有单独的号码实体。使用Id和Number字段创建新的数字实体,然后将Contact与Number实体建立一对多的关系。

然后序列化程序可以正常工作以列出多个数字。

// Contact.orm.xml

<one-to-many field="numbers" target-entity="Number" mapped-by="number" index-by="NumberId"/>


// Contact.php

/**
 * @var \Doctrine\Common\Collections\Collection
 */
protected $numbers;

public function __construct()
{    
   $this->numbers= new \Doctrine\Common\Collections\ArrayCollection();
}

public function addNumber(Number $numbers)
{
    $this->numbers[] = $numbers;

    return $this;
}

public function getNumbers()
{
    return $this->numbers;
}

答案 1 :(得分:-1)

通过实验,我发现这有效:

<?php
/**
* Symfony Serializer experiment  
*/
require $_SERVER['DOCUMENT_ROOT'].'/libraries/symfony/vendor/autoload.php';

use Symfony\Component\Serializer\Serializer;
use Symfony\Component\Serializer\Encoder\XmlEncoder;
use Symfony\Component\Serializer\Encoder\JsonEncoder;
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
use Symfony\Component\Serializer\Normalizer\ArrayDenormalizer;

Class Number {
    private $Number;
    // Getters    
    public function getNumber()
    {
        return $this->Number;
    }
    // Setters    
    public function setNumber($number)
    {
        $this->Number = $number;

        return $this;
    }          
} 

class Contact
{
    private $Name;
    private $Numbers;

    // Getters
    public function getName()
    {
        return $this->Name;
    }
    public function getNumbers()
    {
        return $this->Numbers;
    }  
    // Setters
    public function setName($name)
    {
        $this->Name = $name;

        return $this;        
    }
    public function setNumbers($numbers)
    {
        $this->Numbers = $numbers;

        return $this;        
    }
    public function addNumber($number) {
        $this->Numbers['Number'][] = $number;
    }    
}

$data = <<<EOF
<Contact>
    <Name>foo</Name>
    <Numbers>
        <Number>02378415326</Number>
        <Number>07865412354</Number>        
    </Numbers>        
</Contact>
EOF;

// The default Root tag for the XmlEncode is <response>. Not what we want so let's change it to <Contact>
$xmlEncoder = new XmlEncoder();
$xmlEncoder->setRootNodeName('Contact');                

$encoders = array($xmlEncoder, new JsonEncoder());

$normalizers = array(new ObjectNormalizer(), new ArrayDenormalizer());

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

//$jsonContent = $serializer->serialize($searchId, 'json');

$contact = $serializer->deserialize($data, Contact::class, 'xml');

$contact->addNumber('01234567890');

$xmlContent = $serializer->serialize($contact, 'xml');

echo "<pre lang=xml>";
echo htmlentities($xmlContent);
echo "</pre>";     
?>

在xml(xml-&gt; php)上运行反序列化后,我得到的Contact对象能够添加更多的数字。

输出:

<?xml version="1.0"?>
<Contact>
    <Name>foo</Name>
    <Numbers>
        <Number>02378415326</Number>
        <Number>07865412354</Number>
        <Number>01234567890</Number>
    </Numbers>
</Contact>

它使用两个方向,不使用其他指令。