【问题标题】:php classes... validationphp 类...验证
【发布时间】:2010-07-15 06:41:52
【问题描述】:

我正在做一个 php 验证类 带有扩展它的子类,例如移动、郊区、信用卡等

所以,你可以打电话

$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);
    }
}

作为一个非常基本的例子

但是有没有更好的方法呢?

【问题讨论】:

    标签: php validation oop class


    【解决方案1】:

    您可以这样做,但可以改进。让实际的验证器封装自己的验证逻辑是很好的。从基类扩展它们不是。让我们来实现一个接口。这样,任何类都可以成为 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 即可使用它们。

    【讨论】:

      【解决方案2】:

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

      class ValidatorFactory {
          public static function get($type) {
              $validator = "Validator_$type";
              return new $validator();
          }
      }
      
      $valid = ValidatorFactory::get('mobile')->validate($number);
      

      当然需要一些错误检查等,但你应该明白

      【讨论】:

        【解决方案3】:
        ...
        public function type($type) {
            return new self($type);
        }
        ...
        

        注意:这个每次都会返回一个新的 Validator 类实例,因此最好按照 Dennis 的建议使用工厂模式,或者不将新的 Validator 绑定到 type() 方法。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2013-12-18
          • 2012-02-03
          • 2011-11-23
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多