表单验证类的结构

时间:2011-06-09 06:16:33

标签: php oop validation forms

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

1 个答案:

答案 0 :(得分:7)

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

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

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

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

但是,如果您对它感到好奇,那么可以通过多种方式之一

让我们来看看你需要的东西:你说的是 表格 ,需要 验证 使用一个或多个 验证 功能。然后你谈到一个函数,它告诉你 表单是否通过了验证 ,结果你得到了 错误列表验证阶段

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

因此,考虑具有FormValidator个实例列表的ValidationRule类是很自然的,其中每个实例都在验证过程中进行了分析。通过调用validate的{​​{1}}函数完成此验证过程。此外,每个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; }
}

有些注意事项:

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