如何将上下文传递给 Symfony Serializer?

问题描述 投票:0回答:1

我在框架之外使用 Symfony Serializer 组件。我有自定义规范化器,我想从字段中向它传递一些额外的上下文,如下所示:

class TariffDto
{
    #[Context([EntityNormalizer::UNIQUE_ENTITY_FIELD => 'code'])]
    public Product $product;
}

EntityNormalizer 不扩展任何标准化器,它只是实现 DenormalizerInterface (在这种情况下我不需要 NormalizerInterface):

class EntityNormalizer implements DenormalizerInterface
{
    public const UNIQUE_ENTITY_FIELD = 'unique_entity_field';

    private EntityManager $em;

    public function __construct()
    {
        $this->em = Registry::getInstance()->EM;
    }

    public function supportsDenormalization(mixed $data, string $type, ?string $format = null, array $context = []): bool
    {
        return str_starts_with($type, 'App\\Entity\\') && (is_numeric($data) || is_string($data));
    }

    public function denormalize(mixed $data, string $type, ?string $format = null, array $context = [])
    {
        dump($context);
        return $this->em->getRepository($type)->find($data);
    }
}

并且

dump($context)
打印此结果:

^ array:3 [
  "_read_attributes" => false
  "cache_key" => "45e90c83367464cde5c29c1ac70e95f3-product"
  "deserialization_path" => "product"
]

我使用这个序列化器配置:

$phpDocExtractor = new PropertyInfo\Extractor\PhpDocExtractor();
$typeExtractor   = new PropertyInfo\PropertyInfoExtractor(
    typeExtractors: [$phpDocExtractor, new ReflectionExtractor()]
);
$serializer = new Serializer\Serializer(
    normalizers: [
        new BackedEnumNormalizer(),
        new EntityNormalizer(), // my custom normalizer
        new Serializer\Normalizer\ObjectNormalizer(
            nameConverter: new Serializer\NameConverter\CamelCaseToSnakeCaseNameConverter(),
            propertyTypeExtractor: $typeExtractor
        ),

        new Serializer\Normalizer\ArrayDenormalizer(),
    ],
);

我做错了什么,我错过了什么?
我尝试传递不同的上下文键,包括。现有的(

#[Context([DateTimeNormalizer::FORMAT_KEY => 'Y-m-d'])]
),但没有任何改变,我在反规范化方法中仍然没有额外的上下文。

我找到了这篇文章,这里的描述完全符合我的要求,我想它对那个人有用。

那么,我的上下文在哪里?

php symfony deserialization symfony-serializer
1个回答
0
投票

您还需要初始化 ClassMetadataFactory 和 AnnotationLoader 来处理属性。

如果您独立使用序列化器,则必须自己配置所有内容,包括属性的处理。如果您不使用独立序列化器,Symfony 将为您执行此操作。

$phpDocExtractor = new PhpDocExtractor();
$typeExtractor   = new PropertyInfoExtractor(
    typeExtractors: [$phpDocExtractor, new ReflectionExtractor()]
);
$serializer = new Serializer(
    normalizers: [
        new BackedEnumNormalizer(),
        new EntityNormalizer(),
        new ObjectNormalizer(
            classMetadataFactory: new ClassMetadataFactory(new AnnotationLoader()),
            nameConverter: new CamelCaseToSnakeCaseNameConverter(),
            propertyTypeExtractor: $typeExtractor
        ),
        new ArrayDenormalizer()
    ],
);

我对你的课程进行了测试并检查了它。

来自这个人的亲切问候。 ;-)

© www.soinside.com 2019 - 2024. All rights reserved.