gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-02 12:10:20 26 4
gpt4 key购买 nike

我必须记录每个实体的更改。我有监听器,用于监听 preRemovepostUpdatepostDelete 上的教条事件。我的实体 AccessModule 具有关系:

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;

在监听器中: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();
}

我遇到序列化问题当我使用 $log->setData($entity) 时,我遇到了 Circular 问题。当我进行序列化 $log->setData($this->serializer->serialize($entity, ''json) 时,我与 parent 的 child 、与 child 的 child 之间充满了关系。我得到完整的树:/我想得到

预期

[
'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
]

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

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

最佳答案

您正在寻找的东西称为序列化组:herehere .

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

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;
}

您还有用户实体:

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;
}

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

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

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

现在如何让 Symfony 了解这些内容?

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

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

围绕 native symfony 序列化程序构建某种包装服务是件好事,这样您就可以简化整个过程并使其更可重用。

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

这也是“处理”循环引用的一种方法(以及其他方法)。

现在您只需考虑如何格式化结果集。

关于serialization - Symfony 4序列化没有关系的实体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48569537/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com