首页 > 解决方案 > 用于序列化的自定义循环引用处理程序

问题描述

尝试序列化导致一些循环引用问题的实体

class Comment
{
    /**
     * @var Discussion
     *
     * @ORM\ManyToOne(targetEntity="App\Entity\Discussion", inversedBy="comments")
     * @ORM\JoinColumn(nullable=false)
     */
    private $discussion;
}

class Discussion
{
    /**
     * @var Comment[]|ArrayCollection
     *
     * @ORM\OneToMany(targetEntity="App\Entity\Comment", mappedBy="discussion")
     */
    private $comments;
}

由于我Serializer通过注入来使用组件,因此SerializerInterface我尝试使用以下方法扩展我的组件framework.yaml

serializer:
    circular_reference_handler: App\Utils\CircularReferenceHandler

处理程序类实现了__invoke简单地返回对象 ID 的方法:

public function __invoke($object, string $format = null, array $context = [])
{
    if (method_exists($object, 'getId')) {
        return $object->getId();
    }
    return '';
}

不幸的是,这不起作用,我导致无限循环(超过可用内存)。我究竟做错了什么?

标签: phpsymfony

解决方案


如果我理解正确,您正在尝试使用序列化程序并且您遇到了导致循环引用错误的 ManyToOne 关系问题。

我过去解决了这个问题:

$normalizer->setignoredattributes()

这允许您忽略您尝试序列化的对象的忽略属性。所以这样你只会将讨论引用序列化为评论,而不是评论对象引用回讨论。您将忽略评论对象引用回讨论。

use Symfony\Component\Serializer\Serializer;
use Symfony\Component\Serializer\Encoder\JsonEncoder;
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;

$normalizer = new ObjectNormalizer();
$normalizer->setIgnoredAttributes(array('age'));
$encoder = new JsonEncoder();

$serializer = new Serializer(array($normalizer), array($encoder));
$serializer->serialize($person, 'json');

这里的关键是:

$normalizer->setIgnoredAttributes(array('age')); 

这只是您可以在此处阅读的文档中的示例:https ://symfony.com/doc/current/components/serializer.html#ignoring-attributes


推荐阅读