Как я могу использовать datetimeNormalizer в Symfony 4?

Это мой контроллер:

use Symfony\Component\Serializer\Normalizer\DateTimeNormalizer;
use Symfony\Component\Serializer\SerializerInterface;
use Symfony\Component\Serializer\Serializer;
use Symfony\Component\Serializer\Normalizer\GetSetMethodNormalizer;
use Symfony\Component\Serializer\Encoder\JsonEncoder;


public function index($slug, Request $request, SerializerInterface $serializer)
  {
    $table = $this->getDoctrine()->getRepository($EntityName)->findAll();
    $serializer = new Serializer(array(new DateTimeNormalizer('d.m.Y'), new GetSetMethodNormalizer()), array('json' => new JsonEncoder()));
    $data = $serializer->serialize($table, 'json');
    return $this->render('index.html.twig', ['data' => $data]);
  }

Он работает хорошо, но я получаю предупреждение:

User Deprecated: Passing configuration options directly to the constructor is deprecated since Symfony 4.2, use the default context instead.

Создайте настраиваемый нормализатор как службу и пометьте его serializer.normalizer, чтобы SerializerPass мог получить его при построении экземпляра. Внедрите NormalizerInterface, чтобы вы могли безопасно нормализовать и денормализовать, как вам нравится, и это должно помочь.

Artamiel 22.12.2018 17:50

@Artamiel Спасибо! Звучит очень подробно. Это единственное решение? Почему Symfony делает это более сложным в новой версии?

user10800263 22.12.2018 18:02

Что ж, я не говорю, что ваше решение неверно или неточно, но когда дело доходит до Symfony, все немного иначе, чем при независимом использовании Компонента. Предупреждение, которое вы получаете, просто пытается сказать вам использовать все возможности Dependency Injection (как вы это делали с внедрением SerializerInterface) вместо того, чтобы создавать уже существующую службу вручную. Итак, дайте ему шанс.

Artamiel 22.12.2018 18:14
Стоит ли изучать 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 нам нужно возвращать клиентам разные ответы в зависимости от возникшего исключения.
1
3
2 652
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

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

Простое решение - передать массив в качестве первого аргумента:

new Serializer(
    array(
        new DateTimeNormalizer(array('datetime_format' => 'd.m.Y')),
        new GetSetMethodNormalizer()
    ),
    array(
        'json' => new JsonEncoder()
    )
);

Так что просто замените d.m.Y на array('datetime_format' => 'd.m.Y').

Поскольку вы все равно передаете SerializerInterface, вы можете вместо этого настроить свой сериализатор в файле services.yaml:

services:
    _defaults:
        ... # other default settings
        bind:
            Symfony\Component\Serializer\SerializerInterface $dateSerializer: '@app.date_serializer'

    Symfony\Component\Serializer\Normalizer\GetSetMethodNormalizer: ~
    Symfony\Component\Serializer\Encoder\JsonEncoder: ~

    app.date_normalizer:
        class: Symfony\Component\Serializer\Normalizer\DateTimeNormalizer
        arguments:
            - { 'datetime_format': 'd.m.Y' }

    app.date_serializer:
        class: Symfony\Component\Serializer\Serializer
        arguments:
            - ['@app.date_normalizer', '@Symfony\Component\Serializer\Normalizer\GetSetMethodNormalizer']
            - ['@Symfony\Component\Serializer\Encoder\JsonEncoder']

Затем в вашем контроллере вы можете просто ввести свой сериализатор, изменив имя аргумента

public function index($slug, Request $request, SerializerInterface $dateSerializer)

Фактически, где бы вы ни захотели повторно использовать этот сериализатор, вы можете получить его, просто введя его с помощью SerializerInterface $dateSerializer благодаря привязке в конфигурации вашей службы.

Примечание: привязка будет работать только с Symfony 4.2. В более старых версиях вам необходимо удалить тип в начале (SerializerInterface), поскольку это новая функция. Думаю, все остальное должно работать с Symfony 3.4 и 4.0.

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