表单验证类的结构

Jan*_*nee 1 php forms oop validation

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

nic*_*083 7

当我阅读你的帖子时,我想到了你写的内容:

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

如果您使用对象验证,那么想法是无法在无效状态下创建对象.如果您尝试使用无效数据修改它,则会引发异常.这使得表单易于使用.您唯一需要做的就是填充对象并观察在该过程中抛出的异常.这只是让你入门并了解解决这个问题的另一种方法的想法.

关于你关于表单验证的问题,正如其他人所说的那样,最好不要重新发明轮子并寻找现有的,经过验证的验证框架.

但是,如果您对此感到好奇,可以采用以下方法之一:

让我们来看看你需要的东西:你在谈论一个需要通过一个或多个验证功能验证表单.然后,您将讨论一个函数,该函数告诉您表单是否通过了验证,因此您获得了验证阶段发现的错误列表.

当你谈到OOP时,要走的路是通过代表它的类来给出你的问题域(表单验证的领域)实体的每个概念或想法,模拟他们的行为.

因此,考虑FormValidator具有ValidationRule实例列表的类是很自然的,其中每个实例都在验证过程中进行了分析.这个验证过程是通过调用validate函数来完成的FormValidator.此外,ValidationRule作为调用自己的validate方法的一个实例,每个都会给出一个实例ValidationRuleResult,告诉验证是否成功,以及错误消息和有关验证的其他数据(如果需要).一旦评估了所有验证规则,该类的validate方法FormValidator将返回一个类的实例,该实例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; }
}
Run Code Online (Sandbox Code Playgroud)

您可以通过以下方式创建验证规则:

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

有些事情需要注意:

  • 我假设$ aForm是字段名称/值的关联数组
  • 您可以注意到,如果验证规则通过,则不使用结果(因为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);        
}
Run Code Online (Sandbox Code Playgroud)