Form Validation Class
Posted: Mon Oct 13, 2008 9:03 am
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.
Usage:
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.
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 != '');
}
}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
}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.