php - 在 PHP 中链接检查的优雅方式
问题描述
假设您有一个通用的验证功能,并且您必须对输入进行几次子检查。它们中的每一个也返回布尔值。看这个虚构的:
private function hasValidContent(string $content) : bool
{
$isValid = false;
$isValid = $this->hasMoreThanOneChar($content);
$isValid = $this->hasValidCharacters($content);
$isValid = $this->hasCapitalLetters($content);
...
return $isValid;
}
当然,上面的代码不会起作用,因为每次下一次检查都会覆盖前一次的评估。
但是,当第一次检查导致 时,如何停止进一步检查false
?例如,如果它的内容不超过一个字符,那么它应该在hasMoreThanOneChar
函数之后停止并hasValidContent
立即将方法返回为 false。
是的,当然,您可以在每个方法调用后检查表达式是否变为 false,但这很尴尬,而且开销和重复很多。
||
如果有数千个或&&
类似的情况,单次执行它也感觉非常难看
return $this->checkA($content)
&& $this->checkB($content)
&& $this->checkC($content)
...;
再多表达几句后,可读性会受到影响。
另一个经常提到的方法可能是使用异常
private function hasValidContent(string $content) : bool
{
try {
$this->hasMoreThanOneChar($content);
$this->hasValidCharacters($content);
$this->hasCapitalLetters($content);
...
}
catch {
return false;
}
return true;
}
private function hasMoreThanOneChar(string $string) : void {
if(count($string) < 2 ) {
throw new HasNotMoreThanOneCharException(...)
}
}
但我也认为这不是一个优雅的解决方案,因为验证东西并没有什么特别之处。
所以我的问题:
有什么优雅的模式吗?我可以搜索任何关键字吗?
解决方案
创建一个包含您要执行的所有验证的数组。数组的每个元素都必须是可调用的。迭代并提前退出。如果所有验证者都通过了,那就很好。
private function hasValidContent(string $content) : bool
{
$validators = [
// instance method
[$this, 'hasMoreThanOneChar'],
// callable class
new class {
public function __invoke(string $content)
{
return ...;
}
},
// anonymous function
function (string $content): bool {
return ...;
}
];
foreach ($validators as $validate) {
if (!$validate($content)) {
return false;
}
}
return true;
}
推荐阅读
- html - 如何在 HTML 中为 Tooltip> 的指针添加阴影
- algorithm - 如何做到这一点嵌套的循环时间复杂度?
- javascript - 未捕获的错误引导需要 jquery 在 bootstrap.min.js
- jquery - 取消选择后无法再次选择选项
- laravel - Laravel 测试文件下载总是失败
- node.js - 谷歌助理会话实体有时工作有时不工作.. nodejs
- php - 如何根据 PHP/Laravel 中的值打印或存储具有选定属性的 html 选择标签?
- python - 使用 xlsxwriter 居中对齐(无条件格式)
- sql - 这个访问查询有什么问题?
- hybris - Smartedit 中的重叠组件