【发布时间】:2021-06-10 17:07:49
【问题描述】:
我需要将一个对象序列化为它自己的属性(它的类型是数组),我的意思是这个对象有一个数组属性books,转换之后我想跳过books这个键,所以结构会更平坦[book1, book2](不是[books => [book1, book2]]。我有以下课程:
<?php
class Store
{
private ?BooksCollection $booksCollection = null;
public function __construct(?BooksCollection $booksCollection = null)
{
$this->booksCollection = $booksCollection;
}
public function getBooksCollection(): ?BooksCollection
{
return $this->booksCollection;
}
}
class BooksCollection
{
/** @var Book[] */
private array $books;
public function __construct(Book ...$books)
{
$this->books = $books;
}
public function getBooks(): array
{
return $this->books;
}
}
class Book
{
private string $title;
public function __construct(string $title)
{
$this->title = $title;
}
public function getTitle(): string
{
return $this->title;
}
}
和序列化配置:
Store:
exclusion_policy: ALL
properties:
booksCollection:
type: BooksCollection
BooksCollection:
exclusion_policy: ALL
properties:
books:
type: array<int, Book>
Book:
exclusion_policy: ALL
properties:
title:
type: string
我想通过的测试:
<?php
use JMS\Serializer\ArrayTransformerInterface;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
class StoreSerializeTest extends KernelTestCase
{
/** @var ArrayTransformerInterface */
private $serializer;
protected function setUp(): void
{
self::bootKernel();
$this->serializer = self::$kernel->getContainer()->get('jms_serializer');
}
public function testSerialization(): void
{
$store = new Store(new BooksCollection(new Book('Birdy'), new Book('Lotr')));
$serializedStore = $this->serializer->toArray($store);
$storeUnserialized = $this->serializer->fromArray($serializedStore, Store::class);
self::assertSame(
[
'books_collection' => [
['title' => 'Birdy'],
['title' => 'Lotr']
]
],
$serializedStore
);
self::assertEquals($store, $storeUnserialized);
}
}
正如您在下面看到的,测试失败了。我怎样才能摆脱一个嵌套的“书”?
我的主要想法是使用EventSubscriberInterface 和onPreSerialize 事件,但我真的不知道如何将对象BooksCollection 替换为由其自身属性books 组成的数组。有没有人已经知道怎么做?
【问题讨论】:
-
为什么不使用扩展 IterratorAggregate 并序列化他的书项的类 BookCollection ? Insteed JMS Serializer,你应该使用 Symfony Serializer 组件:)
-
我已经尝试过使用虚拟财产
public function getIterator(): Iterator { return new ArrayIterator($this->books); },但是商店序列化的结果仍然有关键的“书籍”
标签: php symfony serialization jmsserializerbundle jms-serializer