Developing a Form Validation System with the Observer Pattern in PHP - Getting the whole picture: listing the full source code for the data checking classes (
Page 4 of 4 )
Culled from my own experience, I know that it’s much better to have all the source code listed in one place. For this simple reason, below I’ve listed all the data validation classes that I’ve defined in the previous section, so you can have a clear idea of how all the pieces fit together. Here they are:
// define DataValidator class
class DataValidator{
protected $method;
protected $formObserver;
public function __construct(FormObserver $formObserver){
$this->formObserver=$formObserver;
$this->method=$_POST;
}
protected function notifyObserver($errorMessage){
$this->formObserver->addNotification($errorMessage);
}
}
// define StringValidator class
class StringValidator extends DataValidator{
public function __construct($formObserver){
parent::__construct($formObserver);
}
// validate strings
public function validate($field,$errorMessage,$min=4,$max=32){
if(!isset($this->method[$field])||trim($this->method
[$field])==''||strlen($this->method[$field])<$min||strlen($this-
>method[$field])>$max){
$this->notifyObserver($errorMessage);
}
}
}
// define IntegerValidator class
class IntegerValidator extends DataValidator{
public function __construct($formObserver){
parent::__construct($formObserver);
}
// validate integers
public function validate($field,$errorMessage){
if(!isset($this->method[$field])||!is_numeric($this-
>method[$field])||intval($this->method[$field])!=$this->method
[$field]){
$this->notifyObserver($errorMessage);
}
}
}
// define NumberValidator class
class NumberValidator extends DataValidator{
public function __construct($formObserver){
parent::__construct($formObserver);
}
// validate numbers
public function validate($field,$errorMessage){
if(!isset($this->method[$field])||!is_numeric($this-
>method[$field])){
$this->notifyObserver($errorMessage);
}
}
}
// define RangeValidator class
class RangeValidator extends DataValidator{
public function __construct($formObserver){
parent::__construct($formObserver);
}
// validate ranges
public function validate($field,$errorMessage,$min=1,$max=99){
if(!isset($this->method[$field])||$this->method[$field]
<$min||$this->method[$field]>$max){
$this->notifyObserver($errorMessage);
}
}
}
// define AlphaValidator class
class AlphaValidator extends DataValidator{
public function __construct($formObserver){
parent::__construct($formObserver);
}
// validate alphabetic field
public function validate($field,$errorMessage){
if(!isset($this->method[$field])||!preg_match("/^[a-zA-Z]
+$/",$this->method[$field])){
$this->notifyObserver($errorMessage);
}
}
}
// define AlphanumValidator class
class AlphanumValidator extends DataValidator{
public function __construct($formObserver){
parent::__construct($formObserver);
// validate alphanumeric data
public function validate($field,$errorMessage){
if(!isset($this->method[$field])||!preg_match("/^[a-zA-
Z0-9]+$/",$this->method[$field])){
$this->notifyObserver($errorMessage);
}
}
}
// define EmailValidator class
class EmailValidator extends DataValidator{
public function __construct($formObserver){
parent::__construct($formObserver);
}
// validate email
public function validate($field,$errorMessage){
if(!isset($this->method[$field])||!preg_match
("/.+@.+..+/",$this->method[$field])||!checkdnsrr(array_pop
(explode("@",$this->method[$field])),"MX")){
$this->notifyObserver($errorMessage);
}
}
}
// define EmailValidatorWin class (Windows systems)
class EmailValidatorWin extends DataValidator{
public function __construct($formObserver){
parent::__construct($formObserver);
}
public function validate($field,$errorMessage){
if(!isset($this->method[$field])||!preg_match
("/.+@.+..+/",$this->method[$field])||!$this->windnsrr(array_pop
(explode("@",$this->method[$field])),"MX")){
$this->notifyObserver($errorMessage);
}
}
// private method 'windnsrr()' for Windows systems
private function windnsrr($hostName,$recType=''){
if(!empty($hostName)){
if($recType=='')$recType="MX";
exec("nslookup -type=$recType $hostName",$result);
foreach($result as $line){
if(preg_match("/^$hostName/",$line)){
return true;
}
}
return false;
}
return false;
}
}
Here you have it. Now that you have the entire set of data validation classes listed in one place, feel free to improve them, in accordance with your specific programming requirements. It’s truly educational, believe me.
To wrap up
In this second article, you learned how to build a data validation system which uses independent objects for checking the validity of a broad range of user-supplied input, and also is capable of sending information about errors to a core object when user data fails to pass the verification process. However, the application is still incomplete, since the “core object” that I mentioned before remains undefined.
But, there’s no reason to panic. In the last article, I’ll show you how to define an observer object at the application’s core level, in this way providing the program with a centralized mechanism for making programmatic decisions based upon the errors that occurred when validating user-provided data. I'll meet you in the last tutorial!