Symfony version(s) affected
7.4
Description
Trying to decode a valid JSON object into a DTO fails for nullable \DateTimeInterface properties (also concrete implementations) with:
Unexpected "string" value for "DateTimeInterface|null".
The generated code seems to check for array data:
$providers['DateTimeInterface|null'] = static function ($stream, $offset, $length) use ($options, $valueTransformers, $instantiator, &$providers) {
$data = \Symfony\Component\JsonStreamer\Read\Decoder::decodeStream($stream, $offset, $length);
if (\is_array($data)) {
return $providers['DateTimeInterface']($data);
}
if (null === $data) {
return null;
}
throw new \Symfony\Component\JsonStreamer\Exception\UnexpectedValueException(\sprintf('Unexpected "%s" value for "%s".', \get_debug_type($data), 'DateTimeInterface|null'));
};
return $providers['App\TestDto']($stream, 0, null);
How to reproduce
<?php
declare(strict_types = 1);
namespace App;
use Symfony\Component\JsonStreamer\Attribute\JsonStreamable;
#[JsonStreamable]
class TestDto
{
public int $id;
public \DateTimeInterface $date;
public ?\DateTimeInterface $nullable = null;
}
<?php
declare(strict_types = 1);
namespace App;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\JsonStreamer\StreamReaderInterface;
use Symfony\Component\TypeInfo\Type;
use Symfony\Contracts\HttpClient\HttpClientInterface;
#[AsCommand(
name : 'app:test',
description: 'Test command',
)]
readonly class TestCommand
{
public function __construct(
private HttpClientInterface $httpClient,
private StreamReaderInterface $jsonStreamReader,
) {
}
public function __invoke(): int
{
$response = $this->httpClient->request('GET', 'https://fify.website/__object.json');
/** @var TestDto $dto */
$dto = $this->jsonStreamReader->read($response->toStream(), Type::object(TestDto::class));
dump($dto->id);
dump($dto->date);
dump($dto->nullable);
return Command::SUCCESS;
}
}
{
"id": 100,
"date": "2026-02-03T08:38:26+01:00",
"nullable": "2026-02-03T08:38:26+00:00"
}
Possible Solution
Maybe this check isn't working correctly?
|
if ($type instanceof ObjectType) { |
|
return "\\is_array($accessor)"; |
|
} |
Additional Context
No response
Symfony version(s) affected
7.4
Description
Trying to decode a valid JSON object into a DTO fails for nullable \DateTimeInterface properties (also concrete implementations) with:
The generated code seems to check for array data:
How to reproduce
{ "id": 100, "date": "2026-02-03T08:38:26+01:00", "nullable": "2026-02-03T08:38:26+00:00" }Possible Solution
Maybe this check isn't working correctly?
symfony/src/Symfony/Component/JsonStreamer/Read/PhpGenerator.php
Lines 289 to 291 in 386a8cc
Additional Context
No response