Page 1 of 1

Form Validation Class

Posted: Mon Oct 13, 2008 9:03 am
by Stryks
Ok ... So, I've been using a validation class I made up when ages ago during one of my earlier forays into OOP. I wont post it here because .. well .. it's terrible. But let's just say that I want to start from scratch and create a class that I can easily adapt to any form I may be working with.

But as usual, I'm on the back of a 4 hour search session and I now have too much information to make heads or tails of anything.

I have managed to turn up something that looks like what I was fuzzily visualizing, many thanks to arborint.

Code: Select all

class Validator {
    var $chain = array();
    var $errorMsg = array();
 
    function addRule(&$rule) {
        if (is_array($rule)) {
            $this->chain = array_merge($this->chain, $rule);
        } else {
            $this->chain[] = $rule;
        }
    }
 
    function validate ($request) {
        $this->errorMsg = array();
        foreach ($this->chain as $rule) {
            if (! $rule->isValid($request)) {
                $this->errorMsg[] = $rule->getErrorMsg();
            }
        }
        return $this->isValid();
    }
 
    function isValid() {
        return empty($this->errorMsg);
    }
 
    function getErrorMsg() {
        return $this->errorMsg;
    }
 
} // end class Validator
 
class Rule {
    var $field;
    var $errorMsg;
 
    function getErrorMsg() {
        return $this->errorMsg;
    }
}
 
class RuleNotNull extends Rule {
    function RuleNotNull($field, $errorMsg) {
        $this->field = $field;
        $this->errorMsg = $errorMsg;
    }
 
    function isValid($request) {
        $value = $request[$this->field];
        return ($value != '');
    }
}
Usage:

Code: Select all

$validator = new Validator();
$validator->addRule(new RuleNotNull('username', 'Username required'));
$validator->addRule(new RuleNotNull('password', 'Password required'));
$validator->validate($_POST);
if ($validator->isValid()) {
// form is valid
header('Location: form_done.php');
} else {
// get error messages
$errormsg = 'Errors: ' . implode(', ', $validator->getErrorMsg());
// show form and error message
}
By the way, if anyone can point me towards a more recent implementation, that'd be great.

Anyhow ... I'm just after some opinions on this approach. It seems to be very similar to a few examples I found around the place. THIS is a good example, but the above adds a very nice twist by holding the tests in a class array, removing that part of it from the implementation side of things.

Anyhow, where my question lies is in two main areas.

The first relates to possibly including filtering functions in the class. For clarification, by validation I mean "making sure the data received meets these requirements", where filtering would mean "taking data known to fit certain rules and outputting that information in a set format".

I was thinking that alongside the validation rules would be a set of filter rules that could be called on request to return filtered data. For example, if a form requires a credit card number, then the cc validation rule would state "numbers or spaces only, 16 digits in total". The filter would produce the valid result as a 16 digit number with any spacing removed.

Any thoughts on this?

The second issue is basically about applying multiple tests to a field. I'm assuming that multiple tests would just be placed one after the other? I'm assuming so, and testing seems to back this up. I'm thinking I'll stop all tests on a field after it fails one item, so that any one field will return one error, despite how many tests it would have failed. Then I'm thinking I'll use the field name as a key for the error message so I can tie the error to its generating field for display purposes.

Also, any thoughts on using this for GET and POST on the same page? Two instances, or just use REQUEST?

Any thoughts appreciated ... I'm all out. :roll:

Re: Form Validation Class

Posted: Mon Oct 13, 2008 2:04 pm
by Christopher
What you show is the Skeleton Validator and Rules. Ninja just did a revamp of these Skeleton classes that are an update of what you show above. There is also a similar set of Filter classes. In addition Skeleton has a specific 'model' class for forms -- it considers the form data to conceptually be a model. This class allows you to associate Rules and Filters with each form field or the whole form. You can use it as an external model class if you want, or use it directly in the Controller, as controller code, like you show above.

I know Ninja looked at a lot of forms classes. The Skeleton design makes the trade-off that simple forms are more work to implement, but the curve then flattens out and increasingly complex form rules are straightforward to code. Multiple rules per field, multi-field rules, array field rules are all doable, plus it is easy to write custom rules. There is also HTML generation.

Re: Form Validation Class

Posted: Mon Oct 13, 2008 5:56 pm
by Stryks
Thanks for the response arborint.

I had a look around and turned up skeleton at google code. Is that the revamp you mention, or is it elsewhere.

Either way, I'll take a look at that skeleton code and see what I can see.

Cheers

Re: Form Validation Class

Posted: Mon Oct 13, 2008 6:33 pm
by Christopher
Stryks wrote:I had a look around and turned up skeleton at google code. Is that the revamp you mention, or is it elsewhere.
That's it. The download is out of date as we just went through a series of change. If you don't want to mess with SVN let me know and I will PM you a ZIP file of the latest.