bugarinov / chain-validation
实现数据验证责任链模式的类。主要用于处理复杂的验证。
Requires
- php: ^7.2 || ^8.0
Requires (Dev)
- phpunit/phpunit: ^9.5
README
注意
最新版本是 0.2.x,与 0.1.x 版本**不兼容**。有关详细信息,请参阅 迁移。
或者,您可以阅读 0.1.x-README.md 以了解 0.1.x 版本。
Chain Validation 是一个简单的 PHP 库,用于处理超出检查给定数据类型、格式和值的非常复杂的验证。它使用 责任链 设计模式来依次执行每个验证。一旦在链中的某个链接的验证过程中发生错误,执行将停止。您可以根据需求在链中修改数据。
用法
定义和执行验证
用法简单。首先,根据目的/相关性对验证进行分组,并为每个验证组创建一个新的类,该类扩展 AbstractLink
类。
class ValidationOne extends AbstractLink { public function evaluate(?array $data): EvaluationResult { /* * Run your validation process here which will * set the value of $validationFailed whether * the validation failed (true) or not (false) */ if ($validationFailed) { return new ResultFailed('your error message here', 400); } /* * If the validation did not fail, return an * evaluation result which contains the data */ return new ResultSuccess($data); } }
您可以使用 ChainValidation
类运行验证。链将按照精确顺序或 先进先出 顺序执行每个验证。
$chain = new ChainValidation(); $chain->add(new ValidationOne()); $chain->add(new ValidationTwo()); $chain->add(new ValidationThree()); $chain->add(new ValidationFour()); $validatedData = $chain->execute($data);
捕获错误
要判断是否发生错误,您可以使用 ChainValidation
类的 hasError()
函数,并在验证执行后使用 getErrorMessage()
函数获取错误消息。您可以使用 getErrorCode()
函数获取相应的错误代码。
$validatedData = $chain->execute($data); if ($chain->hasError()) { throw new Exception($chain->getErrorMessage()); // or your preferred way of handling errors e.g. returing a response } // Some processes here if the validation succeeds e.g. committing of data to the database commitToDatabase($validatedData);
如果链验证成功,它将返回 验证后的数据,否则它将返回 null
。
具有主体的错误
在某些情况下,错误消息不足以说明问题,尤其是在前端应用程序中,它们会在 UI 上突出显示特定错误。因此,在 ResultFailed
类的构造函数中添加了一个新参数,以便将此数据传递给链。
$errorBody = [ 'items_with_error' => [ [ 'item_uid' => '100012', 'reason' => 'something went wrong' ] ] ]; return new ResultFailed('Some items have errors!', 400, $errorBody);
可以通过 ChainValidation
类的 getErrorBody()
函数和 LinkInterface
实现获取错误数据。
// Example of returning an error response using PSR's ResponseInterface $validatedData = $chain->execute($data); if ($chain->hasError()) { $payload = [ 'statusCode' => $chain->getErrorCode(), 'error' => $chain->getErrorMessage(), 'body' => $chain->getErrorBody() ]; $response->getBody() ->write(json_encode($payload)); return $response->withStatus($error_code) ->withHeader('Content-type', 'application/json'); }
从 0.1.x 迁移到 0.2.x
要从 0.1.x 迁移到 0.2.x,您只需在每个链接中将 execute
函数替换为 evaluate
函数。
v0.1.x
class ValidationOne extends AbstractLink { public function execute(?array $data): ?array { if ($validationFailed) { return $this->throwError('your error message here', 400); } return $this->executeNext($data); } }
到 v0.2.x
class ValidationOne extends AbstractLink { public function evaluate(?array $data): EvaluationResult { if ($validationFailed) { return new ResultFailed('your error message here', 400); } return new ResultSuccess($data); } }
测试
使用 composer test
运行测试。
添加了对 Link
的 evaluate
函数的模拟测试 测试。