0
我希望创建一个自定义验证器。但我不想每次都致电new
,因为这会使测试更加困难。我也认为App::make
是一个有点丑陋。我只想依赖注入我的自定义验证器并使用它。使用克隆PHP伪不可变对象
我对如何做到这一点的想法是使用clone
。调用验证方法将设置克隆的属性,而不是$ this。这样,该类的DI版本保持不变。这种测试/模拟也很容易。
这是一个合适的模式/我应该只使用new
?
我的自定义验证
class CustomValidator
{
protected $rules = [
'key' => 'required',
];
protected $errors = [];
public function validate(array $event): CustomValidator
{
$v = Validator::make($event, $this->rules);
if ($v->fails()) {
$copy = clone $this;
$copy->errors = $v->errors()->toArray();
return $copy;
}
return $this;
}
public function hasErrors(): bool
{
return !empty($this->errors);
}
public function getErrors(): array
{
return $this->errors;
}
}
用法:
foreach ($events as $event) {
// customValidator is immutable. $v is cloned
$v = $this->customValidator->validate($event);
if ($v->hasErrors()) {
// do something with $v->errors();
continue;
}
// No errors... Do something else
}
嗯,如果'应用:: make'长相丑陋,那么Laravel可能不是最好的选择。这是使用容器的非常习惯的方式,并且框架严重依赖于它。默认情况下'bind'注册非共享服务,即你从容器中获得一个新的实例。 –
这不仅仅是'App :: make'看起来很丑。国际海事组织 - 通过使用克隆,它减少了错误的可能性。例如忘记“App:make”或忘记“new”会导致未来迭代中的错误。例如通过填充'errors'数组,并在随后的调用中保留这个artefact - 即使在代码的其他地方。 – Gravy
不太清楚我的理解*忘记*到'App :: make'比'clone'忘记*更糟糕,但在你的情况下它真的很重要。一般来说,克隆是稍微不同的,因为克隆共享注入对象的相同实例,这可能是也可能不是期望的行为。 –