Как десериализовать DateTime в этом случае?

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

У меня есть простой JSON, например:

[{"id":"00112063002463454431","first_name":"John","last_name":"Doe","date_of_birth":"2006-09-28"}]

Теперь я хотел бы сопоставить его с моим классом Person. Что бы я ни пробовал, он всегда жалуется, что date_of_birth является строкой. Ожидается, что это будет DateTimeInterface, когда подпрограмма внутренне вызывает setDateOfBirth(?DateTimeInterface $dateOfBirth) внутри класса Person. Но, насколько я понимаю, denormalize() DateTimeNormalizer должен был уже преобразовать его в объект DateTime, прежде чем он гидратирует объект Person, не так ли?

Внутри моего класса поле определяется следующим образом:

#[ORM\Column(type: Types::DATE_MUTABLE)]
#[Context([DateTimeNormalizer::FORMAT_KEY => 'Y-m-d'])]
private ?DateTimeInterface $dateOfBirth = null;

Процесс десериализации:

    $serializer = new Serializer(
        [new DateTimeNormalizer(), new GetSetMethodNormalizer(), new ArrayDenormalizer()],
        [new JsonEncoder()]
    );

    $personsFromJson = $serializer->deserialize($requestContent, 'App\Entity\Person[]', 'json');

Есть ли что-нибудь еще сделать?!

Редактировать

Пример одного класса:

<?php

namespace App\Controller;

use DateTimeInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Serializer\Annotation\Context;
use Symfony\Component\Serializer\Encoder\JsonEncoder;
use Symfony\Component\Serializer\Normalizer\DateTimeNormalizer;
use Symfony\Component\Serializer\Normalizer\GetSetMethodNormalizer;
use Symfony\Component\Serializer\Serializer;

class TestController extends AbstractController
{
    #[Route(path: '/test', name: 'app_test')]
    public function index(): Response
    {
        $json = '{"dateOfBirth":"2023-01-31"}';

        $serializer = new Serializer(
            [new DateTimeNormalizer(), new GetSetMethodNormalizer()],
            [new JsonEncoder()]
        );

        $testPersonFromJson = $serializer->deserialize($json, TestPerson::class, 'json');

        return $this->json($testPersonFromJson);
    }
}

class TestPerson {
    #[Context([DateTimeNormalizer::FORMAT_KEY => 'Y-m-d'])]
    private ?DateTimeInterface $dateOfBirth = null;

    public function getDateOfBirth(): ?DateTimeInterface {
        return $this->dateOfBirth;
    }
    public function setDateOfBirth(?DateTimeInterface $dateOfBirth): self {
        $this->dateOfBirth = $dateOfBirth;

        return $this;
    }
}

App\Controller\TestPerson::setDateOfBirth(): Аргумент №1 ($dateOfBirth) должен иметь тип ?DateTimeInterface, заданная строка, называется в [...]\vendor\symfony\serializer\Normalizer\GetSetMethodNormalizer.php в строке 163

Создается экземпляр DateTimeNormalizer(), но на самом деле denormalize() никогда не вызывается.

Я не уверен, но, возможно, порядок нормализаторов может иметь значение. Не могли бы вы попробовать расположить их в таком порядке: ArrayDenormalizer, DateTimeNormalizer, GetSetMethodNormalizer?

Ilia Yatsenko 31.01.2023 12:10

Ничего не меняет, к сожалению.

Krann Sock 31.01.2023 12:21

Я добавил пример контроллера, содержащий мою проблему.

Krann Sock 31.01.2023 13:23
Стоит ли изучать 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 нам нужно возвращать клиентам разные ответы в зависимости от возникшего исключения.
0
3
69
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Мне пришлось добавить ReflectionExtractor в мой ObjectNormalizer. Я нигде этого не замечал.

new ObjectNormalizer(null, null, null, new ReflectionExtractor())

https://symfony.com/doc/current/components/property_info.html#reflectionextractor

Найдено в комментариях после моего 18567-го поиска по адресу: Symfony Serialize Entity with Datetime / Deserialize не работает

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