我在框架之外使用 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'])]
),但没有任何改变,我在反规范化方法中仍然没有额外的上下文。
我找到了这篇文章,这里的描述完全符合我的要求,我想它对那个人有用。
那么,我的上下文在哪里?
您还需要初始化 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()
],
);
我对你的课程进行了测试并检查了它。
来自这个人的亲切问候。 ;-)