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

Symfony 6反序列化JSON数组遇异常,求配置与数组解码方案

问题分析与解决方案

一、先修复JSON语法错误

你提供的JSON字符串存在语法错误:{"action": "RFDF", "count": 172}"多了一个多余的双引号,这会直接导致JSON解析异常,修正后的正确JSON如下:

{"expert": "foo", "username": "bar", "activity": [{"action": "RFDF", "count": 172},{"action": "RETA", "count": 10},{"action": "AS", "count": 3}]}

二、Serializer反序列化异常的原因与修复

1. 模型设计逻辑错误

你的ActivityModel同时存放整个activity数组和单个action/count属性,且@SerializedPath("[activity][action]")无法处理数组类型的路径(Serializer不知道要取数组中哪一个元素的action),这是核心矛盾点。正确的做法是拆分模型:

步骤1:创建单个活动项模型

<?php

declare(strict_types=1);

namespace App\Model;

class ActivityItemModel
{
    private string $action;
    private int $count; // count是数字类型,建议用int而非string

    public function getAction(): string
    {
        return $this->action;
    }

    public function setAction(string $action): self
    {
        $this->action = $action;
        return $this;
    }

    public function getCount(): int
    {
        return $this->count;
    }

    public function setCount(int $count): self
    {
        $this->count = $count;
        return $this;
    }
}

步骤2:修改主模型并配置Serializer

主模型只保留顶层属性和活动数组,同时需要添加ArrayDenormalizer来处理数组类型的属性:

<?php

declare(strict_types=1);

namespace App\Model;

class ActivityModel
{
    private string $expert;
    private string $username;
    /** @var ActivityItemModel[] */
    private array $activity;

    public function getExpert(): string
    {
        return $this->expert;
    }

    public function setExpert(string $expert): self
    {
        $this->expert = $expert;
        return $this;
    }

    public function getUsername(): string
    {
        return $this->username;
    }

    public function setUsername(string $username): self
    {
        $this->username = $username;
        return $this;
    }

    /**
     * @return ActivityItemModel[]
     */
    public function getActivity(): array
    {
        return $this->activity;
    }

    /**
     * @param ActivityItemModel[] $activity
     */
    public function setActivity(array $activity): self
    {
        $this->activity = $activity;
        return $this;
    }
}

步骤3:修正反序列化代码

添加ArrayDenormalizer并启用类型提示检测:

use Symfony\Component\Serializer\Serializer;
use Symfony\Component\Serializer\Encoder\JsonEncoder;
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
use Symfony\Component\Serializer\Normalizer\ArrayDenormalizer;
use App\Model\ActivityModel;

$encoders = [new JsonEncoder()];
// 必须添加ArrayDenormalizer来处理数组类型属性
$normalizers = [new ArrayDenormalizer(), new ObjectNormalizer()];
$serializer = new Serializer($normalizers, $encoders);

$context = [
    ObjectNormalizer::TYPE_HINT_DETECTION => true, // 自动识别类型注解
    ObjectNormalizer::COLLECT_DENORMALIZATION_ERRORS => true // 收集错误便于调试
];

$activityModel = $serializer->deserialize($json, ActivityModel::class, 'json', $context);

三、备选方案:直接将JSON解码为数组

不需要使用Symfony Serializer,直接用PHP内置函数即可:

// 第二个参数设为true,返回关联数组
$dataArray = json_decode($json, true);

// 检查JSON解析是否成功
if (json_last_error() !== JSON_ERROR_NONE) {
    throw new \RuntimeException('JSON解析失败:' . json_last_error_msg());
}

// 使用数组数据
var_dump($dataArray['expert']);
var_dump($dataArray['activity']);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 09:08:08