简体   繁体   中英

Custom circular reference handler for serialization

Trying to serialize an entity which causes some circular reference issues

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

Since I'm using the Serializer component via injecting the SerializerInterface I tried to extend my framework.yaml with:

serializer:
    circular_reference_handler: App\Utils\CircularReferenceHandler

Where the handler class implements the __invoke method which simply returns the ID of the object:

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

Unfortunately this doesn't work and I'm resulting in an endless loop (exceeding available memory). What am I doing wrong?

If I understand correctly, you're trying to use the serializer and you're running into issues with the ManyToOne relationship causing a circular reference error.

I solved this in the past with:

$normalizer->setignoredattributes()

This allows you to ignore ignore attributes of an object your trying to serialize. So this way you will only serialize the discussions reference down to comments, but not the comments objects reference back to discussion. You'll ignore the comments objects reference back to discussion.

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

The key here being:

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

That was simply the example from the documentation which you may read here: https://symfony.com/doc/current/components/serializer.html#ignoring-attributes

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM