2010-07-15 103 views
6

IM想提出一个PHP的验证类 与扩展它的子类,如移动,郊区,CREDIT_CARD,ECTPHP类...验证

如此,倒也可以拨打

$validation = new Validation('mobile'); 
$valid = $validation->validate($number); 

$validation->type('suburb'); 
$valid2 = $validation->validate($suburb); 

现在我这样做的想法是有

class Validation() { 
    private $v_type = null; 

    function __construct($type) { 
     $this->type($type); 
    } 

    public function type($type) { 
     $this->v_type = new $type(); 
    } 

    public function validate($info) { 
     return $this->v_type->validate($info); 
    } 
} 

一个非常简单的例子

但是有没有更好的方法来做到这一点?

回答

9

你可以这样做,但它可以改善。让实际的验证器自己验证逻辑是很好的。从基类扩展它们不是。我们来实现一个接口。这样,任何类都可以成为一个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。由于验证器也实施了IValidate,因此它也是Composite。您可以从上方取出Validator链并将其堆叠到另一个验证链中,例如

$numericGreaterThanFive = new Validator; 
$numericGreaterThanFive->addValidator(new IsNumeric) 
         ->addValidator(new GreaterThan(5)); 

$otherValidator = new Validator; 
$otherValidator->addValidator(new Foo) 
       ->addValidator(new Bar) 
       ->addValidator($numericGreatherThanFive); 

为了方便,你可以添加一个静态工厂方法用于创建与实际验证Command对象验证器(如别处所示)。

在旁注:the Zend Framework already has an extensive number of Validators you can build on。由于ZF是一个组件库,您可以使用它们而无需将整个应用程序迁移到ZF。

2

通常你做这几样使用工厂模式,像这样的事情:

当然
class ValidatorFactory { 
    public static function get($type) { 
     $validator = "Validator_$type"; 
     return new $validator(); 
    } 
} 

$valid = ValidatorFactory::get('mobile')->validate($number); 

需要一些错误检查等,但你应该明白我的意思

0
... 
public function type($type) { 
    return new self($type); 
} 
... 

注意:每次都会返回一个Validator类的新实例,因此Dennis建议或不要将新的Validator绑定到type()方法时使用Factory模式会更好。