php - 使用 Symfony Serializer 将 JSON 反序列化为类实例数组
问题描述
我正在尝试将 JSON 反序列化为 DTO 类,该类的属性类型为NestedDto[]
. 不幸的是,数组中的对象被反序列化为数组,而不是NestedDto
. 我的 DTO 课程如下:
class TestDto
{
/**
* @var NestedDto
*/
public NestedDto $c;
/**
* @var NestedDto[] $cs
*/
public array $cs;
}
class NestedDto
{
public string $s;
}
编排此用例的代码(我将在问题末尾显示序列化程序的代码):
function main() {
$serializer = new JsonSerializer();
$json = '{"c":{"s":"nested"},"cs":[{"s":"nested1"},{"s":"nested2"}]}';
$dto = $serializer->fromJSON(TestDto::class, $json);
echo '<pre>' . print_r($dto, true) . '</pre>';
$response = $serializer->toJSON($dto);
exit($response);
}
您可以看到该属性c
是正确的NestedDto
,但在cs
数组内部我们有两个数组而不是两个NestedDto
实例。
TestDto Object
(
[c] => NestedDto Object
(
[s] => nested
)
[cs] => Array
(
[0] => Array
(
[s] => nested1
)
[1] => Array
(
[s] => nested2
)
)
)
下面是JsonSerializer
类的代码,它是 Symfony 序列化器的包装器:
final class JsonSerializer
{
private Serializer $serializer;
private ValidatorInterface $validator;
/**
* JsonSerializer constructor.
*/
public function __construct()
{
$encoders = [new JsonEncoder()];
$classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader()));
$normalizers = [
new ObjectNormalizer($classMetadataFactory, NULL, NULL, new ReflectionExtractor()),
new ArrayDenormalizer(),
new DateTimeNormalizer(),
];
$this->serializer = new Serializer($normalizers, $encoders);
$this->validator = Validation::createValidatorBuilder()->enableAnnotationMapping()->getValidator();
}
/**
* Create a DTO class from json. Will also auto-validate the DTO.
* @param $classFQN string The class FQN, e.g. \App\Something\CreateQuoteDTO::class
* @param $json string The string containing JSON we will use for the DTO.
* @return array|mixed|object An instance of the $class.
*/
public function fromJSON( string $classFQN, string $json )
{
$instance = $this->serializer->deserialize($json, $classFQN, 'json');
$errors = $this->validator->validate($instance);
if (count($errors) > 0) {
throw new \RuntimeException('Invalid DTO.');
}
return $instance;
}
/**
* Convert a class instance to JSON string
* @param $object
* @return string
*/
public function toJSON( $object ) : string
{
return $this->serializer->serialize($object, 'json');
}
}
我已经阅读了有关 Stack Overflow 的所有类似问题,但我找不到我的代码中缺少的内容。我的猜测是 JsonSerializer 中使用的规范化器中的某些东西没有正确连接,但是在花费了过多的时间之后,我没有线索了。
这是沙箱中的所有代码,您可以在其中运行它:phpsandbox.io
以防万一,我在本例中使用 composer 所需的包是:
"symfony/serializer-pack": "*",
"symfony/validator": "*",
"doctrine/annotations": "*",
"doctrine/cache": "*",
解决方案
我已经分叉了您的链接,并且在序列化后,我在 $cs 变量中得到了一个 NestedDto 数组。工作解决方案:https ://phpsandbox.io/n/fragrant-field-wgn5
推荐阅读
- excel - 如果日期小于 Excel VBA 删除行
- raspberry-pi - Raspbian 上的调制解调器未与“nmcli”连接
- python - Tkinter 创建图像函数报错:pyimage1 不存在
- angular - ng2-charts 中的范围条形图
- docker - 将 Docker 容器部署到 swarm 集群中的多个节点
- python - 如何正确访问 Django 模板中的嵌套 JSON 对象?
- firebase - 有没有办法根据当前用户 UID 从 Firebase 加载图像到颤振项目
- c# - 在c#中将数据字符串转换为对象
- linux - AWS ECS 创建服务在控制台上显示输出时等待用户输入
- html - 如何让 includeHTML 在多个 TabPanel 中工作?