Symfony 4序列化实体没有关系 [英] Symfony 4 serialize entity wihout relations

查看:68
本文介绍了Symfony 4序列化实体没有关系的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我必须记录每个实体的更改。我有一个Listener,用于监听preRemove,postUpdate和postDelete上的事件。
我的实体AccessModule具有以下关系:

I've have to log changes of each entities. I've Listener which listen for doctrine's events on preRemove, postUpdate and postDelete. My enity 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;

在侦听器中:
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)时遇到序列化
的问题
我要进行序列化 $ log-> setData($ this-> serializer-> serialize($ entity,''json)我与父母的孩子,与孩子的孩子之间建立了充分的关系,结果我得到了全树:/
我想得到

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

期望

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

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

您还拥有用户实体:

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

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

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.

仔细看看 @Groups 批注。您可以指定所谓的序列化组。只是告诉Symfony您想要在结果集中包含哪些数据的简便方法。

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.

您必须告诉Symfony序列化器您希望保留哪些关系在属性/获取器上方以注释的形式添加相关的组。您还必须指定要保留的关系的哪些属性或获取方法。

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.

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

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']]);

最好在本机symfony序列化程序周围构建某种包装服务,以便简化整个过程,并且使它更可重用。

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序列化实体没有关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆