2011-06-09 26 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