自定义循环引用处理程序以进行序列化

时间:2019-02-10 18:54:19

标签: php symfony

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

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

不幸的是,这行不通,并且导致无限循环(超出可用内存)。我在做什么错了?

1 个答案:

答案 0 :(得分:0)

如果我理解正确,那么您正在尝试使用序列化程序,并且遇到了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