You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ApiPlatform 3.1升级至3.2后GroupsDenormalizer注入异常排查

问题原因

ApiPlatform 3.2.0新增了ValidationExceptionNormalizer,这个归一化器会自动装饰api_platform.serializer.normalizer.item服务。你的GroupsDenormalizer同样装饰该服务,但仅实现了DenormalizerInterface,未实现NormalizerInterface。当依赖注入容器构建装饰链时,若ValidationExceptionNormalizer尝试注入你的GroupsDenormalizer作为其装饰对象,就会因类型不匹配抛出TypeError——因为ValidationExceptionNormalizer的构造函数要求参数是NormalizerInterface类型,而你的类只实现了反归一化接口。

解决思路

1. 让GroupsDenormalizer同时实现两个接口

修改你的GroupsDenormalizer类,使其同时实现NormalizerInterface和DenormalizerInterface,并将归一化相关逻辑委托给被装饰的服务:

<?php

namespace App\Security;

use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
use Symfony\Component\Serializer\SerializerAwareInterface;
use Symfony\Component\Serializer\SerializerInterface;
use Symfony\Component\DependencyInjection\Attribute\AsDecorator;

#[AsDecorator(decorates: 'api_platform.serializer.normalizer.item')]
class GroupsDenormalizer implements NormalizerInterface, DenormalizerInterface, SerializerAwareInterface
{
    public function __construct(private readonly NormalizerInterface&DenormalizerInterface $decorated) {}

    // 委托归一化逻辑给被装饰服务
    public function normalize(mixed $object, ?string $format = null, array $context = []): array|string|int|float|bool|\ArrayObject|null
    {
        return $this->decorated->normalize($object, $format, $context);
    }

    public function supportsNormalization(mixed $data, ?string $format = null, array $context = []): bool
    {
        return $this->decorated->supportsNormalization($data, $format, $context);
    }

    // 保留你原有的反归一化逻辑
    public function denormalize(mixed $data, string $type, ?string $format = null, array $context = []): mixed
    {
        // 你的自定义反归一化代码
        return $this->decorated->denormalize($data, $type, $format, $context);
    }

    public function supportsDenormalization(mixed $data, string $type, ?string $format = null, array $context = []): bool
    {
        // 你的自定义支持判断逻辑
        return $this->decorated->supportsDenormalization($data, $type, $format, $context);
    }

    public function setSerializer(SerializerInterface $serializer): void
    {
        if ($this->decorated instanceof SerializerAwareInterface) {
            $this->decorated->setSerializer($serializer);
        }
    }

    // 若需要,实现getSupportedTypes方法(Symfony 6.3+)
    public function getSupportedTypes(?string $format): array
    {
        return $this->decorated->getSupportedTypes($format);
    }
}

2. 调整装饰器优先级(可选)

如果接口修改后仍有问题,可以通过调整priority参数控制装饰链顺序,确保ValidationExceptionNormalizer先于你的GroupsDenormalizer被应用:

#[AsDecorator(decorates: 'api_platform.serializer.normalizer.item', priority: -100)]

(优先级数值越低,装饰器越晚被应用,即越靠近原始服务)

3. 验证服务定义

确保services.yaml中没有冲突的手动配置,若之前手动定义过装饰,删除相关配置,完全依赖#[AsDecorator]属性即可。

内容的提问来源于stack exchange,提问作者Alexandre Tranchant

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 22:03:35