您可以这样做,但可以改进。让实际的验证器封装自己的验证逻辑是很好的。从基类扩展它们不是。让我们来实现一个接口。这样,任何类都可以成为 Validator。
interface IValidate
{
public function validate($value);
}
您的验证器将如下所示:
class IsNumeric implements IValidate
{
public function validate($value)
{
return is_numeric($value);
}
}
和
class GreaterThan implements IValidate
{
protected $_value;
public function __construct($value)
{
$this->_value = $value;
}
public function validate($value)
{
return $value > $this->_value;
}
}
你仍然有一个主要的 Validator 类。与您的示例不同,下面的验证器接受多个验证器,这将允许您创建过滤器链。
class Validator implements IValidate
{
protected $_validators;
public function addValidator(IValidate $validator)
{
$this->_validators[] = $validator;
return $this;
}
public function validate($value)
{
foreach($this->_validators as $validator) {
if ($validator->validate($value) === FALSE) {
return FALSE;
}
}
return TRUE;
}
}
这可以像这样使用:
$validator = new Validator;
$validator->addValidator(new IsNumeric)
->addValidator(new GreaterThan(5));
var_dump( $validator->validate('ten') ); // FALSE
var_dump( $validator->validate('10') ); // TRUE
var_dump( $validator->validate('1') ); // FALSE
上面几乎是Command pattern。由于 Validator 也实现了 IValidate,它也是一个Composite。您可以从上面获取验证器链并将其堆叠到另一个验证器链中,例如
$numericGreaterThanFive = new Validator;
$numericGreaterThanFive->addValidator(new IsNumeric)
->addValidator(new GreaterThan(5));
$otherValidator = new Validator;
$otherValidator->addValidator(new Foo)
->addValidator(new Bar)
->addValidator($numericGreatherThanFive);
为方便起见,您可以添加一个静态工厂方法来使用实际的验证命令对象创建验证器(如其他地方所示)。
附注:the Zend Framework already has an extensive number of Validators you can build on。由于 ZF 是一个组件库,因此您无需将整个应用程序迁移到 ZF 即可使用它们。