我正在尝试使用Symfony创建一个简单的日历。为此,我想通过AJAX请求所选月份的事件。每个事件可以有多个用户连接到它。
现在检索事件非常简单
$events = $this->em->getRepository('AppBundle:Event')
->findByYearMonth($this->getUser(), $year, $month);
$encoder = new JsonEncoder();
$normalizer = new ObjectNormalizer();
$normalizer->setCircularReferenceHandler(function ($object) {
return $object->getId();
});
$serializer = new Serializer([$normalizer], [$encoder]);
$serialized = $serializer->serialize($events, 'json');
$response = new Response($serialized);
$response->headers->set('Content-Type', 'application/json');
我需要setCircularReferenceHandler
,因为显然用户也有连接到他们的事件。
在我的测试中,我目前只有2个事件,但我得到了大约50kb的响应,只是因为它被用户对象膨胀了。我真正想要的只是用户ID和名称,但它检索所有其他字段(以及其他连接的实体)。
循环引用处理程序本身只有在返回用户后才处于活动状态(并在最初检索用户的用户中捕获事件)。
我已经搜索过了,但没有找到一个符合我想要的结果(大多数是关于表单、通用序列化等)。
我唯一的想法是向Event实体添加一个方法,例如getSimple
,在那里我手动设置一些参数并忽略outer(但对于所有连接的东西也必须这样做)。这看起来很不干净,所以我在这里问。
TL;DR
我想要像一样的东西
[
{"id":1, "name":"foo", "users":[
{"id":1, "name":hans"},
{"id":2, "name":"jack"},...
]},...
]
但我得到了类似的东西
[
{"id":1, "name":"foo", "users":[
{"id":1, "name":hans", "events":[1,{"id":3, "name":"this hasnt already been shown"}], "userfield":"var", "anotheruserfield":"bar", "someOtherRelation":{"bla"},
{"id":2, "name":"jack", "events":[1,{"id":3, "name":"this hasnt already been shown"}], "userfield":"var", "anotheruserfield":"bar", "someOtherRelation":{"bla"}},...
]},...
]
如果我理解正确,您希望从对象序列化中排除events
属性(可能还有其他属性)。
JMSSerializer将满足您的需求,因为它允许排除/公开属性和/或限制它们的深度。
Symfony文档的"序列化"一章的末尾提到了该捆绑包。
参见排除策略及其@Exclude
、@Expose
、@Groups
和@MaxDepth
注释。
是的,JMSSerializer提供了Exclude
和其他可能解决此问题的方法,但我决定做一些不同的事情:编写一个自定义EventNormalizer
,它完全符合我的要求,并且不会改变其他实体本身。
$encoder = new JsonEncoder();
$normalizer = new 'AppBundle'Serializer'Normalizer'EventNormalizer();
$serializer = new Serializer([$normalizer], [$encoder]);
$serialized = $serializer->serialize($events, 'json');
和归一化
namespace AppBundle'Serializer'Normalizer;
use Symfony'Component'Serializer'Normalizer'NormalizerInterface;
/**
* Event normalizer
*/
class EventNormalizer implements NormalizerInterface
{
/**
* {@inheritdoc}
*/
public function normalize($object, $format = null, array $context = array())
{
$result = /* using fields from $object */
return $result;
}
/**
* {@inheritdoc}
*/
public function supportsNormalization($data, $format = null)
{
return $data instanceof 'AppBundle'Entity'Event;
}
}