我正在使用 Symfony 并有一个传入的 JSON 负载,如下所示:
[
{
"number": 1,
"description": "Test 1"
},
{
"number": 2,
"description": "Test 2"
},
{
"number": 3,
"description": "Test 3"
}
]
我有一个数据传输对象(DTO)定义如下:
<?php
class MyDto {
public function __constructor(
public readonly int $number,
public readonly int $description,
) {}
}
我的目标是将 JSON 对象数组直接映射到 Symfony 控制器中的 MyDto 对象数组。这是我当前的控制器方法:
public funtion index(#[MapRequestPayload] MyDto $dto) {
...
}
我正在尝试找到一种方法将 JSON 对象数组映射到 MyDto 对象数组,而不需要创建另一个 DTO 来将此数据包装在键下。 Symfony 中是否有内置或有效的方法来执行此操作?
要将 JSON 对象数组直接映射到 Symfony 中的
MyDto
对象数组,您可以使用 Symfony Serializer 组件。但是,您的控制器方法需要稍微调整,因为 Symfony 不会自动将 JSON 对象数组映射到开箱即用的 DTO 数组。
以下是实现此目标的方法:
1。确保正确的 DTO 构造函数:
首先,您的 MyDto 构造函数中有一个小拼写错误。应该是
__construct
,而不是__constructor
:
<?php
class MyDto {
public function __construct(
public readonly int $number,
public readonly string $description,
) {}
}
2。在控制器中使用 Symfony 序列化器:
您可以使用控制器中的
Serializer
服务将 JSON 负载反序列化为 MyDto
对象数组。
您的控制器方法可能如下所示:
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Serializer\SerializerInterface;
class MyController extends AbstractController
{
public function index(Request $request, SerializerInterface $serializer): JsonResponse
{
$jsonContent = $request->getContent();
/** @var MyDto[] $dtos */
$dtos = $serializer->deserialize($jsonContent, 'App\Dto\MyDto[]', 'json');
// Do something with the $dtos array
foreach ($dtos as $dto) {
// Your logic here
}
return new JsonResponse(['status' => 'success']);
}
}
验证示例:
use Symfony\Component\Validator\Validator\ValidatorInterface;
public function index(Request $request, SerializerInterface $serializer, ValidatorInterface $validator): JsonResponse
{
$jsonContent = $request->getContent();
/** @var MyDto[] $dtos */
$dtos = $serializer->deserialize($jsonContent, 'App\Dto\MyDto[]', 'json');
foreach ($dtos as $dto) {
$errors = $validator->validate($dto);
if (count($errors) > 0) {
// Handle validation errors (return response, throw exception, etc.)
}
}
// Proceed with your logic
return new JsonResponse(['status' => 'success']);
}