[英]How to serialize object as its own property (array) using JMS Serializer EventSubscriberInterface (php, symfony)
I need to serialize an object as its own property (it's type is array), I mean that the object has an array property books
, and after transforming it I want to skip the books
key, so the structure will be more flat [book1, book2]
(not [books => [book1, book2]]
. I have the following classes:我需要序列化一个 object 作为它自己的属性(它的类型是数组),我的意思是 object 有一个数组属性
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;
}
}
and serialization config:和序列化配置:
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
The test I want to pass:我想通过的测试:
<?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);
}
}
As you can see below the test is failing.正如您在下面看到的,测试失败了。 How can I get rid of one nesting 'books'?
我怎样才能摆脱一个嵌套的“书”?
The main idea I had, was to use EventSubscriberInterface
and onPreSerialize
event, but I really can't figure out how can I replace an object BooksCollection
with an array made of its own property books
.我的主要想法是使用
EventSubscriberInterface
和onPreSerialize
事件,但我真的不知道如何将 object BooksCollection
替换为由其自己的属性books
组成的数组。 Is there anyone who already know how to do it?有没有人已经知道怎么做?
Finally, I figured it out.最后,我想通了。 I implemented
SubscribingHandlerInterface
我实现
SubscribingHandlerInterface
<?php
use JMS\Serializer\Context;
use JMS\Serializer\GraphNavigatorInterface;
use JMS\Serializer\Handler\SubscribingHandlerInterface;
use JMS\Serializer\JsonDeserializationVisitor;
use JMS\Serializer\JsonSerializationVisitor;
use Book;
use BooksCollection;
class BooksCollectionHandler implements SubscribingHandlerInterface
{
public static function getSubscribingMethods(): array
{
return [
[
'type' => BooksCollection::class,
'format' => 'json',
'method' => 'serialize',
'direction' => GraphNavigatorInterface::DIRECTION_SERIALIZATION,
],
[
'type' => BooksCollection::class,
'format' => 'json',
'method' => 'deserialize',
'direction' => GraphNavigatorInterface::DIRECTION_DESERIALIZATION,
]
];
}
public function serialize(
JsonSerializationVisitor $visitor,
BooksCollection $booksCollection,
array $type,
Context $context
) {
return $visitor->visitArray($booksCollection->getBooks(), ['name' => 'array'], $context);
}
public function deserialize(
JsonDeserializationVisitor $visitor,
array $data,
array $type,
Context $context
): BooksCollection {
$collection = [];
foreach ($data as $book) {
$collection[] =
$visitor->getNavigator()->accept($book, ['name' => Book::class], $context);
}
return new BooksCollection(...$collection);
}
}
service config:服务配置:
books_handler:
class: BooksCollectionHandler
tags:
- { name: jms_serializer.subscribing_handler }
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.