使用注释组序列化
Serialising with annotation groups
Symfony v4.2
我正在尝试使用 symfony 的标准化器和序列化器将我的实体转换为 JSON。
我遵循了群组注释模式,因为这听起来是最直观和面向未来的方法。
根据the docs,我们必须手动实例化ClassMetadataFactory
才能加载AnnotationLoader
。我仍在使用 ObjectNormalizer
,它在使用注释之前运行良好。
这是我的序列化方法:
/**
* @param bool $event Serialize all event fields (except references)
* @param bool $meta Serialize referenced meta instance
* @param bool $targets Serialize referenced target instances
* @param bool $users Serialize referenced user instances
* @param bool $videos Serialize referenced video instances
* @param bool $photos Serialize referenced photo instances
* @return string
*/
public function serialize($event = true, $meta = false, $targets = false, $users = false, $videos = false, $photos = false) {
$serializingGroups = [];
if ($event) {
$serializingGroups[] = 'event';
}
if ($meta) {
$serializingGroups[] = 'meta';
}
if ($targets) {
$serializingGroups[] = "targets";
}
if ($users) {
$serializingGroups[] = 'users';
}
if ($videos) {
$serializingGroups[] = 'videos';
}
if ($photos) {
$serializingGroups[] = 'photos';
}
$classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader()));
$normalizer = new ObjectNormalizer($classMetadataFactory);
$serializer = new Serializer([$normalizer], [new JsonEncoder()]);
$data = $serializer->normalize($this, null, ['groups' => $serializingGroups]);
return $serializer->serialize($data, 'json');
}
如果我不需要对关联进行序列化,这些组可以加快序列化速度。
现在我使用组注释,json 看起来像这样
"{"id":2,
"title":"test",
"description":"<p> test<\/p>",
"subscriptionPrice":"0.00",
"subscriptionUntil":[], // DATE - WHY EMPTY ARRAY?
"start":[], // DATE - WHY EMPTY ARRAY?
"end":[], // DATE - WHY EMPTY ARRAY?
"allDay":false,
"creationDate":[], // DATE - WHY EMPTY ARRAY?
"editDate":[], // DATE - WHY EMPTY ARRAY?
"editable":true,
"startEditable":true,
"durationEditable":true,
"overlap":false,
"color":"#9EABAB",
"backgroundColor":"#9eabab",
"borderColor":"#9eabab",
"textColor":"#000000",
"isRecurring":true,
"meta":[], // ASSOCIATED ENTITY - WHY EMPTY ARRAY?
"targets":[[]] // ASSOCIATED COLLECTION OF ENTITIES - WHY EMPTY ARRAY?
}"
为什么当我不使用注释时它会起作用?
为什么在我使用注释时日期和其他实体为空数组?
尤里卡!
这是我的序列化方法的代码片段:
$classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader()));
$normalizer = new ObjectNormalizer($classMetadataFactory);
$serializer = new Serializer([
// Add a Datetimenormalizer as the first normalizer in the list
new DatetimeNormalizer(),
$normalizer
], [new JsonEncoder()]);
return $serializer->serialize($this, 'json', [
// $serializer->addCircularReferenceHandler() IS DEPRECATED
// define the handler like this:
ObjectNormalizer::CIRCULAR_REFERENCE_HANDLER => function ($event) {
return '/event/'.$event->id;
}
,ObjectNormalizer::GROUPS => $serializingGroups
]);
首先,meta
和 targets
没有序列化的原因是我的 Meta
和 Target
实体导入错误。确保它是:use Symfony\Component\Serializer\Annotation\Groups;
...所以...是的...继续。
当我注释掉 //,ObjectNormalizer::GROUPS => $serializingGroups
时,日期确实序列化了。那么为什么当组没有被注释掉时他们不序列化呢?
我的猜测是 DateTime
class 没有 Groups
注释,因此规范器永远无法获得任何 DateTime
属性
这可以通过添加 DatetimeNormalizer
作为数组中的第一个规范化器来解决:$serializer = new Serializer([new DatetimeNormalizer(),$normalizer])
这就是我的实体正确序列化的方式 :D
Symfony v4.2
我正在尝试使用 symfony 的标准化器和序列化器将我的实体转换为 JSON。
我遵循了群组注释模式,因为这听起来是最直观和面向未来的方法。
根据the docs,我们必须手动实例化ClassMetadataFactory
才能加载AnnotationLoader
。我仍在使用 ObjectNormalizer
,它在使用注释之前运行良好。
这是我的序列化方法:
/**
* @param bool $event Serialize all event fields (except references)
* @param bool $meta Serialize referenced meta instance
* @param bool $targets Serialize referenced target instances
* @param bool $users Serialize referenced user instances
* @param bool $videos Serialize referenced video instances
* @param bool $photos Serialize referenced photo instances
* @return string
*/
public function serialize($event = true, $meta = false, $targets = false, $users = false, $videos = false, $photos = false) {
$serializingGroups = [];
if ($event) {
$serializingGroups[] = 'event';
}
if ($meta) {
$serializingGroups[] = 'meta';
}
if ($targets) {
$serializingGroups[] = "targets";
}
if ($users) {
$serializingGroups[] = 'users';
}
if ($videos) {
$serializingGroups[] = 'videos';
}
if ($photos) {
$serializingGroups[] = 'photos';
}
$classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader()));
$normalizer = new ObjectNormalizer($classMetadataFactory);
$serializer = new Serializer([$normalizer], [new JsonEncoder()]);
$data = $serializer->normalize($this, null, ['groups' => $serializingGroups]);
return $serializer->serialize($data, 'json');
}
如果我不需要对关联进行序列化,这些组可以加快序列化速度。
现在我使用组注释,json 看起来像这样
"{"id":2,
"title":"test",
"description":"<p> test<\/p>",
"subscriptionPrice":"0.00",
"subscriptionUntil":[], // DATE - WHY EMPTY ARRAY?
"start":[], // DATE - WHY EMPTY ARRAY?
"end":[], // DATE - WHY EMPTY ARRAY?
"allDay":false,
"creationDate":[], // DATE - WHY EMPTY ARRAY?
"editDate":[], // DATE - WHY EMPTY ARRAY?
"editable":true,
"startEditable":true,
"durationEditable":true,
"overlap":false,
"color":"#9EABAB",
"backgroundColor":"#9eabab",
"borderColor":"#9eabab",
"textColor":"#000000",
"isRecurring":true,
"meta":[], // ASSOCIATED ENTITY - WHY EMPTY ARRAY?
"targets":[[]] // ASSOCIATED COLLECTION OF ENTITIES - WHY EMPTY ARRAY?
}"
为什么当我不使用注释时它会起作用? 为什么在我使用注释时日期和其他实体为空数组?
尤里卡!
这是我的序列化方法的代码片段:
$classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader()));
$normalizer = new ObjectNormalizer($classMetadataFactory);
$serializer = new Serializer([
// Add a Datetimenormalizer as the first normalizer in the list
new DatetimeNormalizer(),
$normalizer
], [new JsonEncoder()]);
return $serializer->serialize($this, 'json', [
// $serializer->addCircularReferenceHandler() IS DEPRECATED
// define the handler like this:
ObjectNormalizer::CIRCULAR_REFERENCE_HANDLER => function ($event) {
return '/event/'.$event->id;
}
,ObjectNormalizer::GROUPS => $serializingGroups
]);
首先,meta
和 targets
没有序列化的原因是我的 Meta
和 Target
实体导入错误。确保它是:use Symfony\Component\Serializer\Annotation\Groups;
...所以...是的...继续。
当我注释掉 //,ObjectNormalizer::GROUPS => $serializingGroups
时,日期确实序列化了。那么为什么当组没有被注释掉时他们不序列化呢?
我的猜测是 DateTime
class 没有 Groups
注释,因此规范器永远无法获得任何 DateTime
属性
这可以通过添加 DatetimeNormalizer
作为数组中的第一个规范化器来解决:$serializer = new Serializer([new DatetimeNormalizer(),$normalizer])
这就是我的实体正确序列化的方式 :D