Symfony + JMSSerializer throw 500 - handleCircularReference

Я пытаюсь использовать JMSSerializer с Symfony для создания простого json api.

Итак, у меня есть 2 простых объекта (1 пользователь может иметь много автомобилей, каждый автомобиль принадлежит одному пользователю):

class Car
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type = "integer")
     */
    private $id;

    /**
     * @ORM\Column(type = "string", length=255)
     */
    private $name;

    /**
     * @ORM\ManyToOne(targetEntity = "App\Entity\User", inversedBy = "cars")
     * @ORM\JoinColumn(nullable=false)
     */
    private $user;
}

class User extends BaseUser
{
    /**
     * @ORM\Id
     * @ORM\Column(type = "integer")
     * @ORM\GeneratedValue(strategy = "AUTO")
     */
    protected $id;

    /**
     * @ORM\OneToMany(targetEntity = "App\Entity\Car", mappedBy = "user", orphanRemoval=true)
     */
    private $cars;
}

Теперь я хочу получить все Cars с их User.

Мой контроллер:

class CarController extends AbstractController
{
    /**
     * @param CarRepository $carRepository
     *
     * @Route("/", name = "car_index", methods = "GET")
     *
     * @return Response
     */
    public function index(CarRepository $carRepository)
    {
        $cars = $carRepository->findAll();
        $serializedEntity = $this->container->get('serializer')->serialize($cars, 'json');

        return new Response($serializedEntity);
    }
}

Это вызовет ошибку 500:

A circular reference has been detected when serializing the object of class \"App\Entity\Car\" (configured limit: 1)

Хорошо, звучит ясно. JMS пытается получить каждую машину с пользователем, и перейти к машинам и пользователю ....

Итак, мой вопрос: как предотвратить такое поведение? Я просто хочу, чтобы все машины были со своим пользователем, и после этого итерацию нужно остановить.

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Symfony Station Communiqué - 17 февраля 2023 г
Symfony Station Communiqué - 17 февраля 2023 г
Это коммюнике первоначально появилось на Symfony Station , вашем источнике передовых новостей Symfony, PHP и кибербезопасности.
Управление ответами api для исключений на Symfony с помощью KernelEvents
Управление ответами api для исключений на Symfony с помощью KernelEvents
Много раз при создании api нам нужно возвращать клиентам разные ответы в зависимости от возникшего исключения.
2
0
750
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вам нужно добавить проверки максимальной глубины, чтобы предотвратить циклические ссылки. Это можно найти в документации здесь

Обычно вы добавляете аннотацию @MaxDepth(1) или настраиваете max_depth, если используете конфигурацию XML / YML. Затем выполните сериализацию следующим образом:

use JMS\Serializer\SerializationContext;

$serializer->serialize(
    $data,
    'json',
    SerializationContext::create()->enableMaxDepthChecks()
);

Пример класса Car с аннотацией MaxDepth:

class Car
{
    /** 
     * @\JMS\Serializer\Annotation\MaxDepth(1)
     *
     * [..]
     */
     private $user;

Другие вопросы по теме