Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>As i was reading through your post, a question came into my mind about what you write:</p> <p>Why, instead of validating a form, dont you validte your model's objects? I mean, in an OOP way of looking things your model´s object (or domain objects) are the ones who knows what data is valid or not for each of their attributes. Not doint that, and pushing that logic into the UI makes your design fragile, UI dependant and harder to maintain. If you add a new attribute to one of your model's object, you'll have to modify the form validator as well.</p> <p>If you go with <strong>Objects Validation</strong>, the idea is that an object cannot be created in an invalid state. If you try to modify it with invalid data, an exception will be thrown. This makes easy to work with forms. The only think you have to do is populate your objects and watch for exceptions thrown in that process. This is only an idea to get you started and see another way of solving this problem.</p> <p>Regarding your question about <strong>Forms Validation</strong>, as the other guys said, it is always better not to reinvent the wheel and go for an existing, proven, validation framework.</p> <p>However, if you are curious about it, here is <em>one of the many ways</em> you can do it:</p> <p>Let's go through the things you need: you are talking about a <strong><em>form</em></strong> that needs to be <strong><em>validated</em></strong> with one or more <strong><em>validation</em></strong> functions. Then you talk about a function that tells you whether the form <strong><em>passed the validation or not</em></strong>, and as a result you got the <strong><em>list of errors found during the validation phase</em></strong>.</p> <p>As you talk about OOP, the way to go is to give each concept or idea of your problem domain (the domain of form validation) entity via a class that represents it that model the behavior they have.</p> <p>So, it is natural to think about a <code>FormValidator</code> class with a list of <code>ValidationRule</code> instances, where each one colaborates in the validation process. This validation process is done by calling the <code>validate</code> function of the <code>FormValidator</code>. Also, each <code>ValidationRule</code> will give, as result of calling it´s own <code>validate</code> method an instance of the <code>ValidationRuleResult</code> class, that tells whether the validation was successful or not, along with an error message and additional data (if needed) about the validation. Once all the validation rules were evaluated, the <code>validate</code> method of the <code>FormValidator</code> class will return an instance of <code>ValidationResult</code> class, that summarizes all the validation results of the rules evaluated providing the list of errors found.</p> <p>To get this down to earth, here is the sample model we're talking about:</p> <p><strong>A sample implementation</strong></p> <p><strong>Disclaimer:</strong> please bear in mind that, as any design, it may contains flaws. The following is intended to help you to solve your problem, not to be a complete solution.</p> <pre><code>class FormValidator { private $_validationRules; function __construct() { $this-&gt;_validationRules = array(); } // Registers a new validation rule function addRule($aValidationRule) { $this-&gt;validationRules[] = $aValidationRule; } // Validates $aForm, evaluating each of the $_validationRules defined function validate($aForm) { $aValidationResult = new ValidationResult(); foreach($this-&gt;_validationRules as $aValidationRule) { $aValidationRuleResult = $aValidationRule-&gt;validate($aForm); $aValidationResult-&gt;addResult($aValidationRuleResult); } return $aValidationResult; } } abstract class ValidationRule { private $_fieldName; // The form's field name to be validated function __construct($aFieldName) { $this-&gt;_fieldName = $aFieldName; } function fieldName() { return $this-&gt;_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-&gt;_validationRuleResults = array(); } // Registers a validation rule result function addResult($aValidationRuleResult) { $this-&gt;_validationRuleResults[] = $aValidationRuleResult; } // Returns the list of the error messages of the validation rule results that did't passed function errorsFound() { $errors = array(); foreach($this-&gt;validationRuleResults as $aValidationResult) { if ($aValidationResult-&gt;passed()) continue; $errors[] = $aValidationResult-&gt;errorMessage(); } return $errors; } // Tells whether all the validation rule results passed or not function validationPassed() { foreach($this-&gt;validationRuleResults as $validationResult) { if ($validationResult-&gt;passed() == false) return false; } return true; } } class ValidationRuleResult { private $_passed, $_error_message; function __construct($passed) { $this-&gt;_passed = $passed; $this-&gt;_error_message = ''; } // Tells whether the form passed this validation rule or not public function passed() { return $this-&gt;_passed; } public function // The error message should be empty if passed to avoid confusion public function errorMessage { return $this-&gt;passed() ? '' : $this-&gt;_error_message; } public function setErrorMessage($anErrorMessage) { $this-&gt;_error_message = $anErrorMessage; } } </code></pre> <p>You can create a validation rule this way:</p> <pre><code>class NotEmptyValidationRule extends ValidationRule { public function validate($aForm) { $fieldName = $this-&gt;fieldName(); $fieldValue = $aForm[$fieldName]; $passed = !empty($fieldValue); $result = new ValidationRuleResult($passed); if (!$passed) { $result-&gt;setErrorMessage("$fieldName cannot be empty"); } return $result; } } </code></pre> <p>Some things to note:</p> <ul> <li>Im assuming that $aForm is an associative array of field name / value</li> <li>You can note that if a validation rule passes, the result is not used (as the <code>ValidationResult</code> class works only on those results that didn't pass). Remember that this is a sample only for the purpose of helping you, is not a complete solution.</li> </ul> <p><strong>Usage</strong></p> <pre><code> $rule = new NotEmptyValidationRule('name'); $validator = new FormValidator(); $validator-&gt;addRule($rule); $aForm = $__POST['myForm']; $validationResult = $validator-&gt;validate($aForm); if ($validationResult-&gt;validationPassed()) { $errorsFound = $validationResult-&gt;errorsFound(); // do something with the $errorMessage $errorMessage = array_join('&lt;br/&gt;', $errorsFound); } </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload