我需要在插入数据库之前验证一些数据,为此我创建了一个从实体返回无效字段的小服务。验证单个实体时,它可以正常工作。
class EntityValidator
{
protected $validator;
public function __construct(ValidatorInterface $validator)
{
$this->validator = $validator;
}
public function validate($entity)
{
$errors = $this->validator->validate($entity);
$response = null;
if ($errors->count()) {
foreach ($errors as $error) {
$response[$error->getPropertyPath()] = $error->getMessage();
}
}
return $response;
}
}
但是我一直在努力验证更复杂的问题,例如: 这是一个 restful api 端点,它在帖子正文中接收一个带有user_id和百分比的 json,它将验证实体以查看它是否与 symfony 验证器约束映射正确。
public function create(Request $request, EntityValidator $entityValidator)
{
$data = json_decode($request->getContent(), true);
$entityExample = new EntityExample();
$entityExample
->setUserId($data['user_id'])
->setPercentage($data['percentage'])
;
$errors = $entityValidator->validate($entityExample);
// .. do other things ..
return new JsonResponse($errors);
}
但是,假设我收到一个数据数组,并且我一次要插入许多行,并且有一个业务逻辑说"用户的百分比总和需要为 100">
public function create(Request $request, EntityValidator $entityValidator)
{
$data = json_decode($request->getContent(), true);
$totalPercentage = 0;
foreach ($data as $element) {
$entityExample = new EntityExample();
$entityExample
->setUserId($element['user_id'])
->setPercentage($element['percentage'])
;
$totalPercentage += $element['percentage'];
}
$errors = $entityValidator->validate($entityExample);
if ($totalPecentage != 100) {
$errors[] = 'Sum of percentage must be 100';
}
// .. do other things ..
return new JsonResponse($errors);
}
将这种业务逻辑保留在控制器中似乎是错误的,但我不知道它放在哪里,我应该为此创建一个服务吗? 那么每个具有更复杂验证的端点都会创建一个新服务?
- 创建 JSON 请求有效负载的模型表示形式。具有公共属性的模型,没有其他属性。例如,假设模型称为
Sale
。 - 创建一个自定义验证约束,该约束将与模型连接
Sale
。在此验证类中,您将循环访问Sale.percentage
属性并运行验证逻辑。 - 在控制器中,调用序列化程序组件和验证程序组件来验证请求。
上述各点的完整示例:
- 下面的两个链接都有模型示例,但如果您想要更多示例,只需在此页面中按 ctrl+f
json
http://www.inanzzz.com/index.php/posts/symfony - symfony 中的类级自定义断言验证约束
- 在Symfony API中处理请求,响应和异常的简单方法。复制并且不要触摸
AbstractController
.执行UserController::create
为您自己的控制器执行的操作。他在同一控制器中使用$this->data
进行演示,但您应该将其传递给服务并在那里进行处理。