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
相关产品推荐
相关产品推荐

