Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Cannot deserialize top level associative array #57432

Copy link
Copy link
Closed
@idbentley

Description

@idbentley
Issue body actions

Symfony version(s) affected

7.1

Description

I can serialize/deserialize associative arrays that are contained within object with no problem, by specifying an attribute with an appropriate PHPDoc type like: array<string, int>, but trying the same thing at the top level (i.e. passing it to the deserialize function directly) fails with a NotNormalizableValueException: Could not denormalize object of type "array<string,int>", no supporting normalizer found.

How to reproduce

<?php

declare(strict_types=1);

require_once './vendor/autoload.php';

use Symfony\Component\PropertyInfo\Extractor\PhpDocExtractor;
use Symfony\Component\PropertyInfo\PropertyInfoExtractor;
use Symfony\Component\Serializer\Encoder\JsonEncoder;
use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactory;
use Symfony\Component\Serializer\Mapping\Loader\AttributeLoader;
use Symfony\Component\Serializer\Normalizer\ArrayDenormalizer;
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
use Symfony\Component\Serializer\Serializer;


class MapObjValue
{
    /**
     * $json
     *
     * @var array<string, int>
     */
    public ?array $json = null;
}

$phpDocExtractor = new PhpDocExtractor();
$propertyTypeExtractor = new PropertyInfoExtractor(
    typeExtractors: [$phpDocExtractor],
);
$classMetadataFactory = new ClassMetadataFactory(new AttributeLoader());


$encoders = [new JsonEncoder()];
$normalizers = [
    new ArrayDenormalizer(),
    new ObjectNormalizer(propertyTypeExtractor: $propertyTypeExtractor, classMetadataFactory: $classMetadataFactory),
];

$serializer = new Serializer($normalizers, $encoders);

$response = $serializer->deserialize('{"json": {"foo": 1, "bar": 2}}', MapObjValue::class, 'json');

echo 'embedded in obj\n';
var_dump($response);

// Exception thrown here: Uncaught Symfony\Component\Serializer\Exception\NotNormalizableValueException: Could not denormalize object of type "array<string, int>", no supporting normalizer found.
$response2 = $serializer->deserialize('{"foo": 1, "bar": 2}', 'array<string, int>', 'json');

echo 'top level\n';
var_dump($response2);

Possible Solution

No response

Additional Context

It seems like maybe the deserialize function doesn't accept phpdoc types directly and it will deserialize as expected if I specify an array as: int[]. However, I can't find any documentation on how you can specify the keyType using this syntax.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      Morty Proxy This is a proxified and sanitized view of the page, visit original site.