2011-06-09 51 views
1

我想在OOP PHP中创建一个类来验证表单。不过,我在构建这个时遇到了麻烦。 最初我想为每种验证类型(检查提交数据的长度,检查它是否是数字等)创建单独的函数,然后检查数据是否通过了验证测试并将错误传递到数组中。 虽然我的代码变得非常漫长而且难以管理,但我仍然陷入困境 - 我很新,所以如何解决这个问题?表单验证类的结构

+0

你能告诉我们一些代码?你如何处理表单提交?你打印表格的方式如何? – alexn 2011-06-09 06:18:34

+0

你看过[Zend_Validate](http://framework.zend.com/manual/en/zend.validate.html)吗? – zerkms 2011-06-09 06:20:25

+0

@zerkms我没有看Zend_validate,谢谢,我将检查出 – Janee 2011-06-09 06:46:58

回答

7

,因为我是通过您的文章阅读,问题来到我的脑海里约你写的:

为什么,而不是验证表单,不要你validte模型的对象吗? 我的意思是,以OOP方式查看事物的模型对象(或域对象)是那些知道哪些数据对其每个属性都有效的人。不要这样做,并且将该逻辑推入UI会使您的设计变得脆弱,依赖于UI并且难以维护。如果您为模型的某个对象添加新的属性,则还必须修改表单验证器。

如果你跟对象验证,这个想法是,一个对象不能创建在一个无效的状态。如果您尝试使用无效数据对其进行修改,则会引发异常。 这使得使用表格很容易。唯一需要做的就是填充你的对象并观察在这个过程中抛出的异常。 这只是一个想法,让你开始,并看到解决这个问题的另一种方式。

关于您的问题表单验证,正如其他人所说的,最好不要重新发明轮子并寻求一个现有的,经过验证的验证框架。

但是,如果你是好奇吧,这里的很多方面你可以做到这一点之一:

让我们通过你需要的东西:你是在谈论一个形式那需要验证一个或多个验证功能。然后,请您谈一下,告诉表单您是否通过验证或不,并因此你有在验证阶段发现的错误的列表的功能。

至于你说到OOP,要走的路是通过表示它该模型他们的行为的类来给你的问题域(表单验证域)实体的概念或理念。

因此,很自然地想到一个FormValidator类和一个ValidationRule实例列表,其中每个实例都在验证过程中进行协作。该验证过程通过调用FormValidatorvalidate函数完成。此外,每个ValidationRule会给,作为调用的结果it's自己validate方法ValidationRuleResult类的实例,告诉验证是否成功与否,与有关验证错误消息,并且(如果需要)以及其他数据。一旦评估完所有验证规则,FormValidator类的validate方法将返回ValidationResult类的实例,该实例总结评估规则的所有验证结果,提供发现的错误列表。

为了得到这个脚踏实地,这里是我们谈论的样品模型:

示例实现

免责声明:请谨记,任何设计,它可能包含缺陷。以下内容旨在帮助您解决问题,而不是完整的解决方案。

class FormValidator { 
    private $_validationRules; 

    function __construct() { 
      $this->_validationRules = array(); 
    } 

    // Registers a new validation rule 
    function addRule($aValidationRule) { $this->validationRules[] = $aValidationRule; } 

    // Validates $aForm, evaluating each of the $_validationRules defined 
    function validate($aForm) { 
      $aValidationResult = new ValidationResult(); 

      foreach($this->_validationRules as $aValidationRule) { 
        $aValidationRuleResult = $aValidationRule->validate($aForm); 
        $aValidationResult->addResult($aValidationRuleResult); 
      } 

      return $aValidationResult; 
    } 
} 

abstract class ValidationRule { 
    private $_fieldName; 

    // The form's field name to be validated 
    function __construct($aFieldName) { 
      $this->_fieldName = $aFieldName; 
    } 

    function fieldName() { return $this->_fieldName; } 

    // Returns an instance of ValidationResult describing the result of evaluating the ValidationRule in $aForm. 
    abstract public function validate($aForm); 
} 

class ValidationResult { 
    private $_validationRuleResults; 

    function __construct() { 
      $this->_validationRuleResults = array(); 
    } 

    // Registers a validation rule result 
    function addResult($aValidationRuleResult) { 
      $this->_validationRuleResults[] = $aValidationRuleResult; 
    } 

    // Returns the list of the error messages of the validation rule results that did't passed 
    function errorsFound() { 
      $errors = array(); 

      foreach($this->validationRuleResults as $aValidationResult) { 
        if ($aValidationResult->passed()) continue; 
        $errors[] = $aValidationResult->errorMessage(); 
      } 

      return $errors; 
    } 

    // Tells whether all the validation rule results passed or not 
    function validationPassed() { 
      foreach($this->validationRuleResults as $validationResult) { 
        if ($validationResult->passed() == false) return false; 
      } 

      return true; 
    } 
} 

class ValidationRuleResult { 
    private $_passed, $_error_message; 

    function __construct($passed) { 
      $this->_passed = $passed; 
      $this->_error_message = ''; 
    } 

    // Tells whether the form passed this validation rule or not 
    public function passed() { return $this->_passed; } 
    public function 

    // The error message should be empty if passed to avoid confusion 
    public function errorMessage { return $this->passed() ? '' : $this->_error_message; } 
    public function setErrorMessage($anErrorMessage) { $this->_error_message = $anErrorMessage; } 
} 

您可以创建一个验证规则是这样的:

class NotEmptyValidationRule extends ValidationRule { 
    public function validate($aForm) { 
      $fieldName = $this->fieldName(); 
      $fieldValue = $aForm[$fieldName]; 

      $passed = !empty($fieldValue); 
      $result = new ValidationRuleResult($passed); 

      if (!$passed) { 
        $result->setErrorMessage("$fieldName cannot be empty"); 
      } 

      return $result; 
    } 
} 

需要注意以下几点:

  • 林假设$可保存格式,是字段名称的关联数组/值
  • 您可以注意到,如果验证规则通过,则不会使用结果(因为ValidationResult类仅适用于未通过的结果)。请记住,这是一个仅用于帮助您的样本,不是一个完整的解决方案。

使用

$rule = new NotEmptyValidationRule('name'); 
$validator = new FormValidator(); 
$validator->addRule($rule); 

$aForm = $__POST['myForm']; 
$validationResult = $validator->validate($aForm); 

if ($validationResult->validationPassed()) { 
    $errorsFound = $validationResult->errorsFound(); 
    // do something with the $errorMessage 
    $errorMessage = array_join('<br/>', $errorsFound);   
} 
+0

嘿,刚回到这个问题,看到这个非常详细的答案。感谢您抽出时间 - 非常有帮助。 – Janee 2011-10-19 23:48:43

+0

@Janee,你的欢迎:)我很高兴这对你有帮助。干杯! – nick2083 2011-10-20 02:30:44

+0

另一个+1。在这里辛勤工作很少受到其他人的赞赏。 – jp2code 2014-01-03 23:06:03