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

如何使用Symfony 5.3 Serializer将对象关联数组序列化为指定JSON对象

方案1:通过字段序列化回调实现(无需自定义Normalizer,适合单字段定制)

直接在MyObject类的$b属性上绑定序列化逻辑即可,完全不影响a字段的原有序列化规则:

use Symfony\Component\Serializer\Annotation\Callback;

class MyObject
{
    // 其他属性省略

    #[Callback(serialize: 'formatBField')]
    private iterable $b;

    // 字段序列化回调方法
    public function formatBField(): array
    {
        $formatted = [];
        foreach ($this->b as $bItem) {
            $formatted[(string)$bItem->getId()] = $bItem;
        }
        return $formatted;
    }
}

你原有的序列化代码无需做任何修改,Serializer会自动调用该回调处理b字段的输出格式。


方案2:自定义Normalizer(适合多场景复用规则)

如果多个字段都需要按照「对象ID为键、对象本身为值」的规则序列化,可以用自定义Normalizer实现复用:

  1. 先创建自定义Normalizer类
use Symfony\Component\Serializer\Normalizer\ContextAwareNormalizerInterface;
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;

class IdKeyedCollectionNormalizer implements ContextAwareNormalizerInterface
{
    public const ENABLE_ID_KEY = 'enable_id_key';

    public function __construct(
        private ObjectNormalizer $innerNormalizer
    ) {}

    public function normalize($collection, string $format = null, array $context = [])
    {
        $result = [];
        foreach ($collection as $item) {
            $result[(string)$item->getId()] = $this->innerNormalizer->normalize($item, $format, $context);
        }
        return $result;
    }

    public function supportsNormalization($data, string $format = null, array $context = []): bool
    {
        return isset($context[self::ENABLE_ID_KEY])
            && $context[self::ENABLE_ID_KEY] === true
            && is_iterable($data);
    }
}
  1. 将自定义Normalizer注册到Serializer的normalizer列表中,注意要放在默认ObjectNormalizer前面
$serializer = new Serializer([
    new ArrayDenormalizer(),
    new DateTimeNormalizer(),
    // 新增自定义Normalizer
    new IdKeyedCollectionNormalizer(new ObjectNormalizer($classMetadataFactory, $metadataAwareNameConverter, null,  new ReflectionExtractor())),
    new ObjectNormalizer($classMetadataFactory, $metadataAwareNameConverter, null,  new ReflectionExtractor(), null, null, []),
], [new JsonEncoder()]);
  1. 在需要启用该规则的字段上添加上下文注解
use Symfony\Component\Serializer\Annotation\Context;

class MyObject
{
    #[Context([IdKeyedCollectionNormalizer::ENABLE_ID_KEY => true])]
    private iterable $b;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 15:39:04