Symfony 4 序列化没有关系的实体

编程入门 行业动态 更新时间:2024-10-24 11:19:24
本文介绍了Symfony 4 序列化没有关系的实体的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我必须记录每个实体的变化.我有侦听 preRemove、postUpdate 和 postDelete 上的学说事件的监听器.我的实体 AccessModule 有关系:

App\Entity\AccessModule.php

/*** @ORM\OneToMany(targetEntity=App\Entity\AccessModule",mappedBy=parent")* @ORM\OrderBy({id"=ASC"})*/私人 $children;/*** @ORM\ManyToOne(targetEntity=App\Entity\AccessModule", inversedBy=children")* @ORM\JoinColumn(name=parent_id", referencedColumnName=id", nullable=true)*/私人 $parent;/*** @ORM\ManyToMany(targetEntity=App\Entity\AccessModuleRoute", inversedBy=access_modules")* @ORM\JoinTable(name=access_routes",* joinColumns={@ORM\JoinColumn(name=access_module_id", referencedColumnName=id")},* inverseJoinColumns={@ORM\JoinColumn(name=route_id", referencedColumnName=id")})**/私人 $routes;

在监听器中:App\EventListener\EntityListener.php

使用 Symfony\Component\Serializer\Encoder\JsonEncoder;使用 Symfony\Component\Serializer\Encoder\XmlEncoder;使用 Symfony\Component\Serializer\Normalizer\ObjectNormalizer;$encoders = [new XmlEncoder(), new JsonEncoder()];$normalizer = new ObjectNormalizer();$normalizer->setCircularReferenceHandler(function ($object) {返回 $object->getId();});$this->serializer = new Serializer([$normalizer], $encoders);公共函数 createLog(LifecycleEventArgs $args, $action){$em = $args->getEntityManager();$entity = $args->getEntity();if ($this->tokenStorage->getToken()->getUser()) {$username = $this->tokenStorage->getToken()->getUser()->getUsername();} 别的 {$用户名 = '匿名';//TODO 删除匿名.设置空值}$log = 新日志();//$log->setData('dddd')$log->setData($this->serializer->serialize($entity, ''json)->setAction($action)->setActionTime(new \DateTime())->setUser($username)-> setEntityClass(get_class($entity));$em->persist($log);$em->flush();}

我有序列化问题当我使用 $log->setData($entity) 时,我遇到了 Circular 问题.当我做序列化 $log->setData($this->serializer->serialize($entity, ''json) 我充满了关系,与父母的孩子,与孩子的孩子.结果我得到了完整的树:/我想得到

期待

['id' =>ID,'名称' =>名称,'父母' =>parent_id//ManyToOne,我想得到它的 id'孩子' =>[$child_id, $child_id, $child_id]//子数组集合的 $id 数组]

(当然这是在编码为json之前的草稿)

如何在没有完整关系的情况下获得预期数据?

解决方案

你要找的东西叫做序列化组:这里 和 这里.

现在让我解释一下它是如何工作的.这很简单.假设您有发布实体:

class Post{/*** @ORM\Id* @ORM\GeneratedValue* @ORM\Column(type="整数")* @Groups({"default"})*/私人 $id;/*** @ORM\ManyToOne(targetEntity="App\Entity\User\User")* @Groups({"default"})*/私人 $author;}

你还有用户实体:

类用户{/*** @ORM\Id* @ORM\GeneratedValue* @ORM\Column(type="整数")* @Groups({"default"})*/私人 $id;/*** @ORM\Column(type="string", length=40)* @Groups({"default"})*/私人 $firstName;/*** @ORM\Column(type="string", length=40)*/私人 $lastName;}

帖子可以有作者(用户),但我不想每次都返回所有用户数据.我只对 ID 和名字感兴趣.

仔细查看 @Groups 注释.您可以指定所谓的序列化组.这只不过是告诉 Symfony 您希望在结果集中包含哪些数据的便捷方式.

您必须通过在属性/getter 上方以注释的形式添加相关组来告诉 Symfony 序列化程序您希望保留哪些关系.您还必须指定要保留的关系的哪些属性或 getter.

现在如何让 Symfony 知道这些东西?

当您准备/配置您的序列化服务时,您只需提供如下定义的组:

return $this->serializer->serialize($data, 'json', ['groups' => ['default']]);

围绕原生 symfony 序列化程序构建某种包装服务是很好的,这样您就可以简化整个过程并使其更可重用.

还要确保正确配置了序列化程序 - 否则它不会考虑这些组.

这也是处理"循环引用的一种方式(以及其他方式).

现在您只需要研究如何格式化结果集.

I have to log the changes of each entity. I've Listener which listens for doctrine's events on preRemove, postUpdate and postDelete. My entity AccessModule has relations:

App\Entity\AccessModule.php

/** * @ORM\OneToMany(targetEntity="App\Entity\AccessModule", mappedBy="parent") * @ORM\OrderBy({"id" = "ASC"}) */ private $children; /** * @ORM\ManyToOne(targetEntity="App\Entity\AccessModule", inversedBy="children") * @ORM\JoinColumn(name="parent_id", referencedColumnName="id", nullable=true) */ private $parent; /** * @ORM\ManyToMany(targetEntity="App\Entity\AccessModuleRoute", inversedBy="access_modules") * @ORM\JoinTable(name="access_routes", * joinColumns={@ORM\JoinColumn(name="access_module_id", referencedColumnName="id")}, * inverseJoinColumns={@ORM\JoinColumn(name="route_id", referencedColumnName="id")}) * */ private $routes;

in listener: App\EventListener\EntityListener.php

use Symfony\Component\Serializer\Encoder\JsonEncoder; use Symfony\Component\Serializer\Encoder\XmlEncoder; use Symfony\Component\Serializer\Normalizer\ObjectNormalizer; $encoders = [new XmlEncoder(), new JsonEncoder()]; $normalizer = new ObjectNormalizer(); $normalizer->setCircularReferenceHandler(function ($object) { return $object->getId(); }); $this->serializer = new Serializer([$normalizer], $encoders); public function createLog(LifecycleEventArgs $args, $action){ $em = $args->getEntityManager(); $entity = $args->getEntity(); if ($this->tokenStorage->getToken()->getUser()) { $username = $this->tokenStorage->getToken()->getUser()->getUsername(); } else { $username = 'anon'; // TODO Remove anon. set null value } $log = new Log(); // $log->setData('dddd') $log->setData($this->serializer->serialize($entity, ''json) ->setAction($action) ->setActionTime(new \DateTime()) ->setUser($username) ->setEntityClass(get_class($entity)); $em->persist($log); $em->flush(); }

I've problem with serialization When I use $log->setData($entity) I get problem with Circular. Whan I do serialization $log->setData($this->serializer->serialize($entity, ''json) I get full of relations, with parent's children, with children children. In a result I get full tree :/ I'd like to get

Expect

[ 'id' => ID, 'name' => NAME, 'parent' => parent_id // ManyToOne, I'd like get its id 'children' => [$child_id, $child_id, $child_id] // array of $id of children array collection ]

(ofcourse this is draft before encode it to json)

How can I get expected data without full relations?

解决方案

Thing you are looking for is called serialization groups: here and here.

Now let me explain how it works. It's quite simple. Say you have Post Entity:

class Post { /** * @ORM\Id * @ORM\GeneratedValue * @ORM\Column(type="integer") * @Groups({"default"}) */ private $id; /** * @ORM\ManyToOne(targetEntity="App\Entity\User\User") * @Groups({"default"}) */ private $author; }

And you have also User Entity:

class User { /** * @ORM\Id * @ORM\GeneratedValue * @ORM\Column(type="integer") * @Groups({"default"}) */ private $id; /** * @ORM\Column(type="string", length=40) * @Groups({"default"}) */ private $firstName; /** * @ORM\Column(type="string", length=40) */ private $lastName; }

Post can have author(User) but I don't want to return all User data every single time. I'm interested only in id and first name.

Take a closer look at @Groups annotation. You can specify so called serialization groups. It's nothing more than convinient way of telling Symfony which data you would like to have in your result set.

You have to tell Symfony serializer which relationships you would like to keep by adding relevant groups in form of annotation above property/getter. You also have to specify which properties or getters of your relationships you would like to keep.

Now how to let Symfony know about that stuff?

When you prepare/configure your serializaition service you just simply have to provide defined groups like that:

return $this->serializer->serialize($data, 'json', ['groups' => ['default']]);

It's good to build some kind of wrapper service around native symfony serializer so you can simplify the whole process and make it more reusable.

Also make sure that serializer is correctly configured - otherwise it will not take these group into account.

That is also one way(among other ways) of "handling" circular references.

Now you just need to work on how you will format your result set.

更多推荐

Symfony 4 序列化没有关系的实体

本文发布于:2023-10-28 18:31:58,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1537434.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:实体   关系   序列化   Symfony

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!