bartoszbartniczak/symfony-serializer-arrayofobjects-normalizer

Symfony/Serializer 组件的 ArrayOfObjects Normalizer。

dev-master 2017-02-06 16:20 UTC

This package is auto-updated.

Last update: 2024-09-17 06:48:43 UTC


README

Symfony/Serializer 组件的 ArrayOfObjects Normalizer。此 Normalizer 允许对 BartoszBartniczak\ArrayOfObjects 库中的 ArrayObjects 和 ArrayOfObjects 进行(反)序列化。

外部链接

  1. BartoszBartniczak\ArrayOfObjects
  2. BartoszBartniczak\SymfonySerializerArrayObjectNormalizer

配置

<?php

use Symfony\Component\Serializer\Encoder\JsonEncoder;
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
use Symfony\Component\Serializer\Serializer;
use BartoszBartniczak\SymfonySerializer\Normalizer\ArrayOfObjectsNormalizer;
use BartoszBartniczak\SymfonySerializer\Normalizer\ArrayObjectNormalizer;

$normalizers =[
     new ArrayOfObjectsNormalizer(), //add this normalizer for ArrayOfObjects (de-)serialization
    new ArrayObjectNormalizer(), //add this normalizer for ArrayObject (de-)serialization
    new ObjectNormalizer(),
];

$encoders = [
    new JsonEncoder(),
];

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

ArrayObjects (反)序列化

use BartoszBartniczak\ArrayObject\ArrayOfObjects;
use BartoszBartniczak\SymfonySerializer\Normalizer\Fixtures\Person;

$arrayOfObjects = new ArrayOfObjects(Person::class, [
            'einstein' => new Person('Albert Einstein'),
            'tesla' => new Person('Nikola Tesla')
        ]);

$json = $serializer->serialize($arrayOfObjects, 'json');

在 $json 变量中,现在应包含此 JSON 文档

{
  "className": "BartoszBartniczak\\SymfonySerializer\\Normalizer\\Fixtures\\Person",
  "storage": {
    "einstein": {
      "name": "Albert Einstein"
    },
    "tesla": {
      "name": "Nikola Tesla"
    }
  }
}

现在您可以反序列化此对象

$serializer->deserialize($json, ArrayOfObjects::class, 'json');

您不需要定义元素类型。使用 className 参数进行反序列化。

子类(扩展 ArrayofObjects 类)

此 Normalizer 支持对象继承。您可以扩展 ArrayofObjects(例如添加一些方法),并且此 Normalizer 仍然可以(反)序列化对象。

use BartoszBartniczak\ArrayObject\ArrayOfObjects;
use BartoszBartniczak\SymfonySerializer\Normalizer\Fixtures\Person;

class ArrayOfObjectsSubclass extends ArrayOfObjects{
    
}

$arrayOfObjects = new ArrayOfObjectsSubclass(Person::class, [
            'einstein' => new Person('Albert Einstein'),
            'tesla' => new Person('Nikola Tesla')
        ]);

$json = $serializer->serialize($arrayOfObjects, 'json');

$serializer->deserialize($json, ArrayOfObjectsSubclass::class, 'json');

具有自定义构造函数的子类

我们经常创建包含特定类型对象的数组,例如 PersonArray,它只能包含 Person 对象。

new ArrayOfObjects(Person::class)

每次创建应包含 Person 对象的 ArrayOfObjects 时,没有必要定义类型。

您可以创建一个扩展 ArrayOfObjects 的类

class PersonArray extends ArrayOfObjects{

    public function __construct($input = null, $flags = 0, $iterator_class = "ArrayIterator")
        {
            parent::__construct(Person::class, $input, $flags, $iterator_class);
        }

}

唯一的问题是反序列化过程,它使用构造函数来构建对象。因此,您需要定义一个 \Closure 函数,该函数能够创建您的自定义数组。

对于上述示例,它可能看起来像这样

$arrayOfObjectsNormalizer = new ArrayOfObjectsNormalizer();
$arrayOfObjectsNormalizer->addConstructorForClass(PersonArray::class, function (array $data, string $className){
    return new PersonArray($data[ArrayOfObjectsNormalizer::PROPERTY_STORAGE]);
});

然后您需要注册此 Normalizer。

$normalizers =[
    $arrayOfObjectsNormalizer,
    new ArrayObjectNormalizer(),
    new ObjectNormalizer(),
];

$encoders = [
    new JsonEncoder(),
];

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

现在,您可以(反)序列化 PersonArray

$object = new PersonArray([
    'einstein' => new Person('Albert Einstein'),
    'tesla' => new Person('Nikola Tesla')
]);
$json = $serializer->serialize($object, 'json');

$serializer->deserialize($json, PersonArray::class, 'json');