如何配置Symfony序列化器,使其仅在上下文包含所有指定分组时才序列化属性?
如何配置Symfony序列化器,使其仅在上下文包含所有指定分组时才序列化属性?
嗨,我完全懂你的需求——默认情况下Symfony序列化器的分组逻辑是「只要上下文有任意一个匹配的分组就序列化属性」,但你想要的是必须上下文包含属性上标注的所有分组才会把这个属性输出,对吧?
咱们可以通过自定义一个分组转换器来实现这个“AND”逻辑,具体步骤如下:
1. 自定义分组转换器类
创建一个实现GroupsConverterInterface的类,重写分组匹配逻辑,让它只有当上下文包含属性的所有分组时,才允许该属性被序列化:
namespace App\Serializer; use Symfony\Component\Serializer\Mapping\AttributeMetadataInterface; use Symfony\Component\Serializer\Mapping\GroupsConverterInterface; class AllGroupsRequiredConverter implements GroupsConverterInterface { public function getSupportedGroups(AttributeMetadataInterface $attribute, array $context): array { // 获取属性上标注的所有分组 $attributeGroups = $attribute->getGroups(); // 如果属性没设置分组,按默认逻辑处理 if (empty($attributeGroups)) { return []; } // 获取上下文里的分组列表 $contextGroups = $context['groups'] ?? []; // 检查上下文是否包含属性的所有分组(差集为空则说明全包含) $hasAllRequiredGroups = empty(array_diff($attributeGroups, $contextGroups)); // 满足条件就返回属性分组(允许序列化),否则返回空数组(忽略属性) return $hasAllRequiredGroups ? $attributeGroups : []; } }
2. 注册这个转换器服务
在你的config/services.yaml里把这个类注册为序列化器的分组转换器,记得设置优先级确保它覆盖默认的转换器:
services: App\Serializer\AllGroupsRequiredConverter: tags: - { name: serializer.groups_converter, priority: 100 }
3. 测试你的场景
现在回到你的例子,先修正一下属性注解里的小语法错误(少了一个闭合引号):
#[Groups(['show', 'admin'])] public mixed $name;
当你用['groups' => ['show']]作为上下文时,因为缺少admin分组,转换器会返回空数组,序列化器就会忽略$name属性;只有当上下文同时包含show和admin(比如['groups' => ['show', 'admin']])时,这个属性才会被正常序列化输出。
这样就完全满足你要的“所有分组都存在才序列化”的需求啦!
备注:内容来源于stack exchange,提问作者Oleg Vartanov
相关产品推荐
相关产品推荐

