Symfony序列化器-如何对对象数组进行分组?

时间:2019-01-03 09:15:11

标签: php symfony serialization xml-serialization

我需要使用“分组”元素创建XML文件,例如属性。
我有示例对象类:
产品

class Product
{
    private $name;
    private $attributes = [];

    // standard getter/setter for name

    public function getAttributes(): array
    {
        return $this->attributes;
    }

    public function setAttributes(ProductAttribute $attributes): void
    {
        $this->attributes[] = $attributes;
    }
}

ProductAttribute

class ProductAttribute
{
    private $name;
    private $value;

    // standard getters/setters
}

现在,我正在创建Product对象,并使用Symfony的序列化器对其进行序列化:

$product = new Product();
$product->setName('My product');

foreach ($arrayWithAttributes as $attr) {
    $attribute = new ProductAttribute();
    $attribute->setName = $attr['name'];
    $attribute->setValue = $attr['value'];

    $product->setAttributes($attribute);
}

$encoders = array(new XmlEncoder());
$normalizers = array(new ObjectNormalizer());

$serializer = new Serializer($normalizers, $encoders);
$serializer->serialize($product, 'xml');

我正在得到结果:

    <item key="0">
        <name>My product</name>
        <attributes>
            <name>Attribute Name #1</name>
            <value>Attribute Value #1</value>
        </attributes>
        <attributes>
            <name>Attribute Name #2</name>
            <value>Attribute Value #2</value>
        </attributes>
    </item>

但我期望:

    <item key="0">
        <name>My product</name>
        <attributes>
            <attribute>
                <name>Attribute Name #1</name>
                <value>Attribute Value #1</value>
            </attribute>
            <attribute>
                <name>Attribute Name #2</name>
                <value>Attribute Value #2</value>
            </attribute>
        </attributes>
    </item>

我怎么能得到这个?
我已经尝试过:

//Product.php
public function setAttributes(ProductAttribute $attributes)
{
    $this->attributes[]['attribute'] = $attributes;
}

但是我得到了:

    <item key="0">
        <name>My product</name>
        <attributes>
            <attribute>
                <name>Attribute Name #1</name>
                <value>Attribute Value #1</value>
            </attribute>
        </attributes>
        <attributes>
            <attribute>
                <name>Attribute Name #2</name>
                <value>Attribute Value #2</value>
            </attribute>
        </attributes>
    </item>

2 个答案:

答案 0 :(得分:0)

请尝试

$attrArray = [];

foreach ($arrayWithAttributes as $attr) {
    $attribute = new ProductAttribute();
    $attribute->setName = $attr['name'];
    $attribute->setValue = $attr['value'];
    $attrArray[] = $attribute;

}

 $product->setAttributes($attrArray);

然后在您的实体中

$this->attributes['attribute'] = $attributes;

答案 1 :(得分:0)

好吧,我明白了-我必须为规范化器添加ArrayDenormalizer以支持嵌套树并更改Product $attributes属性设置器。最终看起来:

class Product
{
    private $name;
    private $attributes = [];

    // standard getter/setter for name

    public function getAttributes(): array
    {
        return $this->attributes;
    }

    public function setAttributes(ProductAttribute $attributes): void
    {
        $this->attributes['attribute'][] = $attributes;
    }
}

class ProductAttribute
{
    private $name;
    private $value;

    // standard getters/setters
}

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

$product = new Product();
$product->setName('My product');

foreach ($arrayWithAttributes as $attr) {
    $attribute = new ProductAttribute();
    $attribute->setName = $attr['name'];
    $attribute->setValue = $attr['value'];

    $product->setAttributes($attribute);
}

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

$serializer = new Serializer($normalizers, $encoders);
$serializer->serialize($product, 'xml');