Используйте ключ «circular_reference_handler» контекста вместо symfony 4.2

Мне нужно сериализовать объект, и я получаю очень распространенную «ошибку циклической ссылки».

Я использовал старый метод Symfony:

$normalizer = new ObjectNormalizer();
// Add Circular reference handler
$normalizer->setCircularReferenceHandler(function ($object) {
    return $object->getId();
});
$normalizers = array($normalizer);
$encoders = [new JsonEncoder()];
$serializer = new Serializer($normalizers, $encoders);

Эта работа, но с Symfony 4.2 я получаю исключение, которое вы видите в заголовке этого вопроса:

use the "circular_reference_handler" key of the context instead Symfony 4.2

Я не могу найти никаких ссылок на это в документации Symfony, касающейся сериализатора.

https://symfony.com/doc/current/components/serializer.html#handling-circular-references

Кто-нибудь знает, как использовать этот «ключ контекста» вместо старого метода?

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
3
0
2 458
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

вы можете увидеть ссылку на этот ключ конфигурации здесь: https://symfony.com/doc/current/reference/configuration/framework.html#circular-reference-handler документ не был обновлен, чтобы показать использование этого ключа конфигурации

этот ключ конфигурации должен использоваться в одном из ваших файлов конфигурации (например, framework.yml), чтобы установить службу, используемую для обработки циклических ссылок.

serializer:
    circular_reference_handler: App\Service\YourCircularReferenceHandler
Ответ принят как подходящий

К сожалению, это немного скрыто в документации, но вы можете создать класс вместо использования анонимной функции, а затем настроить сериализатор для использования этой службы по умолчанию.

Это часть ссылки на конфигурацию: https://symfony.com/doc/current/reference/configuration/framework.html#reference-serializer-circular-reference-handler.

# config/packages/serializer.yaml

serializer:
    circular_reference_handler: 'App\Serializer\MyCircularReferenceHandler'

Интерфейс не указан. Вместо этого класс должен быть вызываемым. Итак, в вашем случае это может выглядеть так:

class MyCircularReferenceHandler
{
    public function __invoke($object)
    {
        return $object->id;
    }
}

Спасибо за ответ. Однако как я должен использовать этот метод? Я просто отказываюсь от всего $normalizer->setCircularReferenceHandler вместе?

Dennis de Best 12.02.2019 09:36

@DennisdeBest да, вы можете удалить setCircularReferenceHandler. конфиг устанавливает обработчик, который будет автоматически вызываться при обнаружении циклической ссылки.

ᴄʀᴏᴢᴇᴛ 12.02.2019 09:43

Хорошо, я немного запутался, куда поместить ключ round_reference_handler, оказывается, он находится в framework.yaml в framework:serializer:circular_reference_handler Теперь эта функция вызывается правильно. Это оставляет мне ошибку максимального вложения, но это совсем другая тема. Спасибо за вашу помощь

Dennis de Best 12.02.2019 10:08

Кроме того, вы можете предоставить динамический обработчик в свойстве контекста:

public function normalize($user, $format = null, array $context = [])
{
    // Handle circular references
    // DEPRECATED in sf 4.2 : 
    // $this->normalizer->setCircularReferenceHandler(function ($object) {return $object->getId();});

    // Good way in sf > 4.2
    $context['circular_reference_handler'] = function ($object) {return $object->getId();};
    // Return data
    $data = $this->normalizer->normalize($user, $format, $context);
}

Дополнение к ответу @dbrumann, которое почти сработало для меня. В моем приложении Symfony 4.3 для раздела serializer YAML требуется родительский контейнер framework. Так:

# config/packages/serializer.yaml

framework:
    serializer:
        circular_reference_handler: 'App\Serializer\MyCircularReferenceHandler'

И затем в обработчике ссылок:

class MyCircularReferenceHandler {
    public function __invoke($object) {
        return $object->id;
    }
}

Чтобы убедиться, что значения конфигурации загружаются правильно, вы можете использовать консоль Symfony:

$ php bin/console debug:config framework

Если значения конфигурации загружены правильно, вы должны увидеть их в соответствующем разделе выходных данных.

В конфигурации мессенджера вы можете вызвать метод объекта следующим образом:

class CircularReferenceHandler
{
    public function handle($object, string $format, array $context)
    {
        return $object->getId();
    }
}
# config/package/messenger.yaml
framework:
  messenger:
    serializer:
      default_serializer: messenger.transport.symfony_serializer
      symfony_serializer:
        format: json
        context: {circular_reference_handler: 'App\application\Helpers\CircularReferenceHandler::handle'}

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