PHP Validation Class
Encapsulated user input validator
One of the most common and time consuming tasks in web application development is also one of the most important. Input validation. This class encapsulates the validation to keep it in one place and out of your page handling code.
The basic validation checks are based on a class by Nick Geller.
Usage:
I embed the code above in my data objects in a method that persists the object on success, and throws an exception on validation errors so I can can simply do this in my controllers:
I then pass the status and the array of errors to a smarty template that handles the error display. The controller doesn't need to be aware of any business logic, it simply handles the flow of data between the UI and the business objects.
The basic validation checks are based on a class by Nick Geller.
<?php
class Validator
{
private $_fields = array(); /* field objects */
private $_errors = array(); /* errors returned by the validation routine */
private $_isValid; /* valid flag*/
public function __construct($fields=array())
{
$this->_fields = $fields;
}
public function addField($field)
{
$this->_fields[] = $field;
}
public function validate()
{
$this->_isValid = true;
foreach($this->_fields as $currField)
{
$currName = $currField->getName();
$currValue = $currField->getValue();
$currRuleset = $currField->getRules();
foreach ($currRuleset as $currRule)
{
$currValid = true;
$currRuleType = $currRule->getType();
$currRuleTest = $currRule->getTest();
$currRuleErrMsg = $currRule->getMsg();
$field_string_size = strlen($currValue);
switch($currRuleType)
{
case "maxlength":
/* field is greater than maximum allowed lenth */
if($field_string_size > $currRuleTest)
{
$currValid = false;
$this->_isValid = false;
}
break;
case "minlength":
/* field is less than minimum required lenth */
if($field_string_size < $currRuleTest)
{
$currValid = false;
$this->_isValid = false;
}
break;
case "length":
/* field is does not equal to required lenth */
if($field_string_size != $currRuleTest)
{
$currValid = false;
$this->_isValid = false;
}
break;
case "match":
/* field does not match a required value */
if($currValue != $currRuleTest)
{
$currValid = false;
$this->_isValid = false;
}
break;
case "not":
/* fields value is not acceptable */
if($currValue == $currRuleTest)
{
$currValid = false;
$this->_isValid = false;
}
break;
case "alpha":
/* only alphabetical characters are required for this field */
if(!eregi("^[a-zA-Z ]+$", $currValue))
{
$currValid = false;
$this->_isValid = false;
}
break;
case "numeric":
/* only numeric characters are required for this field*/
if(!eregi("^[0-9]+$", $currValue))
{
$currValid = false;
$this->_isValid = false;
}
break;
case "gt":
/* field does not contain a required character */
if($currValue <= $currRuleTest)
{
$currValid = false;
$this->_isValid = false;
}
break;
case "lt":
if ($currValue >= $currRuleTest)
{
$currValid = false;
$this->_isValid = false;
}
break;
case "email":
/* fields value is not acceptable */
if(!preg_match("/^s*[^@ rnt#$%;]+@[^@ rnt#$%;]+.w{2,3}s*$/", $currValue))
{
$currValid = false;
$this->_isValid = false;
}
break;
}
if (!$currValid)
{
$this->_errors[$currName][] = $currRuleErrMsg;
}
}
}
return $this->_isValid;
}
function getErrors()
{
return $this->_errors;
}
}
class Field
{
private $_name;
private $_value;
private $_rules = array();
public function __construct($name,$value=null)
{
$this->_name = $name;
$this->_value = $value;
}
public function addRule($rule)
{
$this->_rules[] = $rule;
}
public function getName()
{
return $this->_name;
}
public function getValue()
{
return $this->_value;
}
public function getRules()
{
return $this->_rules;
}
public function setValue($value)
{
$this->_value = $value;
}
}
class Rule
{
private $_type;
private $_test;
private $_msg;
public function __construct($type, $test, $msg)
{
$this->_type = $type;
$this->_test = $test;
$this->_msg = $msg;
}
public function getType()
{
return $this->_type;
}
public function getTest()
{
return $this->_test;
}
public function getMsg()
{
return $this->_msg;
}
}
//Rule Constants
define("VALIDATE_MAXLENGTH", "maxlength");
define("VALIDATE_MINLENGTH", "minlength");
define("VALIDATE_LENGTH","length");
define("VALIDATE_MATCH","match");
define("VALIDATE_HAS","has");
define("VALIDATE_NOT","not");
define("VALIDATE_IN","in");
define("VALIDATE_ALPHA","alpha");
define("VALIDATE_NUMERIC","numeric");
define("VALIDATE_LESSTHAN", "lt");
define("VALIDATE_GREATERTHAN", "gt");
define("VALIDATE_EMAIL","email");Usage:
$validator = new Validator();
$nameField = new Field('name', $request->getParameter('name'));
$nameField->addRule(new Rule(VALIDATE_MINLENGTH, 1, "Please enter you Name"));
$nameField->addRule(new Rule(VALIDATE_MAXLENGTH, 128, "Name may not contain more than 128 chars"));
$validator->addField($nameField);
$emailField = new Field('email', $request->getParameter('email'));
$emailField->addRule(new Rule(VALIDATE_EMAIL, null, "Please enter a valid email address"));
$emailField->addRule(new Rule(VALIDATE_MAXLENGTH, 128, "Email may not contain more than 128 chars"));
$validator->addField($emailField);
if ($validator->validate())
{
//Do stuff with data
}
else
{
//Handle error
$errors = $validator->getErrors();
}I embed the code above in my data objects in a method that persists the object on success, and throws an exception on validation errors so I can can simply do this in my controllers:
try
{
$contact = new Contact();
$contact->setName($request->getParameter('name'));
$contact->setEmail($request->getParameter('email'));
$contact->setComment($request->getParameter('comment'));
$contact->store();
}
catch (ValidationException $e)
{
$errors = $e->getErrors();
$status = 'validation_error';
}I then pass the status and the array of errors to a smarty template that handles the error display. The controller doesn't need to be aware of any business logic, it simply handles the flow of data between the UI and the business objects.


