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

如何使用JMS Serializer反序列化含未知嵌套属性的JSON?

解决JMS序列化器中动态键嵌套JSON的反序列化问题

嗨,我来帮你搞定这个反序列化的问题!你遇到的场景是Layer对应的JSON里全是未知的动态键(比如480x960、720x360这种),想要把这些内容提取到Doctrine Collection里,还不用保留原来的键值结构对吧?下面给你两种具体的实现方案,看你是要提取键名还是对应的值:

修改Layer DTO实现需求

我们可以用JMS序列化器的注解先接收动态的键值对,再在反序列化完成后做数据处理,把需要的内容转成Collection。

场景1:把动态键名转成Collection

如果你希望通过$project->getLayer()->getItems()拿到包含480x960、720x360这些分辨率字符串的Collection,就用这个版本:

namespace App\DTO;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use JMS\Serializer\Annotation as Serializer;

class Layer
{
    /**
     * 临时存动态键值对的数组
     * @var array
     *
     * @Serializer\Type("array<array>") // 这里的array<array>对应每个键的值是数组,要是值的类型不一样可以调整
     */
    private $dynamicData;

    /**
     * 最终存键名的Collection
     * @var Collection
     */
    private $items;

    /**
     * 反序列化完自动处理数据
     * @Serializer\PostDeserialize
     */
    public function postDeserialize(): void
    {
        // 把所有键名提取出来转成Collection
        $this->items = new ArrayCollection(array_keys($this->dynamicData));
    }

    public function getItems(): Collection
    {
        return $this->items;
    }
}

场景2:把动态键对应的值转成Collection

要是你需要的是每个键对应的数组值(比如JSON里的[]),只需要改一下postDeserialize方法就行:

/**
 * @Serializer\PostDeserialize
 */
public function postDeserialize(): void
{
    // 提取所有值到Collection,直接忽略键名
    $this->items = new ArrayCollection(array_values($this->dynamicData));
}

额外优化:让getLayer()直接返回Collection

如果你不想多一层getItems(),希望调用$project->getLayer()就直接拿到Collection,可以调整你的Project DTO,直接把$layer定义为数组,在getter里转成Collection:

namespace App\DTO;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use JMS\Serializer\Annotation as Serializer;

class Project
{
    /**
     * @var array
     *
     * @Serializer\Type("array<array>")
     */
    protected $layer;

    public function getLayer(): Collection
    {
        // 要键名就用array_keys,要值就用array_values
        return new ArrayCollection(array_keys($this->layer));
    }
}

这样反序列化之后,直接调用$project->getLayer()就能得到你想要的Collection啦~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 08:02:39