Building a Data Validation System with the Prototype Pattern with PHP 5

It’s unusual to create multiple instances of a class, but certainly it may happen during the development of a PHP application. To solve this issue quickly and with minor hassles, the prototype design pattern can be really useful. If you want to learn more about it, this article might be what you need.

Introduction

Welcome to the final part of the series  that began with "The Basics of Using the Prototype Pattern with PHP 5." Comprised of two articles, this series shows you how to work with many instances of a given class using the remarkable functionality provided by the prototype pattern. It complements the theoretical concepts with a certain number of hands-on examples.

If you read the preceding article of the series, you’re already familiar with the logic that drives the prototype pattern, since its implementation is extremely simple. Otherwise, if this pattern doesn’t ring any bells for you, let me give you a brief explanation of how it functions.

Essentially, when the prototype pattern is applied in the context of a given PHP application, there’s a class not surprisingly called "prototype" too, which is the original model followed by all the objects created from it. However, while this feature is common to all the conventional classes, the most interesting aspect of this pattern is that the first object created from the originating class is used to clone other objects, in this way giving us multiple instances of it.

As you can see, the prototype pattern has a rather uncommon implementation. That characteristic is precisely what makes it interesting from a developer’s point of view, aside from its remarkable capacity for working with multiple instances of the same class.

Therefore, taking into account that this pattern can be helpful in situations where a prototype object is required, along with other clones of it, in this final installment of the series I’m going to demonstrate how to use it to build a simple application for checking the validity of incoming data.

I think you’ll find this exercise to be both interesting and fun. So, come with me and let’s learn together how to implement the prototype pattern in a more useful fashion. Let’s begin now!

{mospagebreak title=Building a simple data validation system}

As I said right in the beginning of this article, I’m going to demonstrate how to implement the prototype pattern by creating a simple mechanism for validating input data. As you’ll see, this data checking application will be capable of working with many instances of a specific object, which will be used to verify the validity of certain data types, such as email addresses, alphanumeric and alphabetic values, etc.

Okay, having explained how I plan to apply the prototype pattern in this particular situation, please have a look at the signatures of the following prototype classes. They establish a generic structure for validating alphanumeric and alphabetic strings.

Here are the prototype classes:

// define abstract ‘DataValidatorPrototype’ class
abstract class DataValidatorPrototype{
   abstract public function validateData($inputData);
   abstract public function __clone();

}

// define concrete ‘AlphabeticValidatorPrototype’ class
class AlphabeticValidatorPrototype extends DataValidatorPrototype{
   public function validateData($inputData){
     if(!$inputData||!preg_match("/^[a-zA-Z]+$/",$inputData)){
       return false;
     }
     return true;
   }
   public function __clone(){}
}

// define concrete ‘AlphanumericValidatorPrototype’ class
class AlphanumericValidatorPrototype extends DataValidatorPrototype{
   public function validateData($inputData){
     if(!$inputData||!preg_match("/^[a-zA-Z0-9]+$/",$inputData)){
       return false;
     }
     return true;
   }
   public function __clone(){}
}

As illustrated above, the three classes are very convenient for checking certain types of data, and come in handy for working with alphabetic and alphanumeric values.

Of course, you’ll realize that the first abstract class, the one called "DataValidatorPrototype," is used to define the generic characteristics of any data validator object that might be potentially derived from it. However, aside from studying in detail the functionality provided by these classes, you should notice that each of them declares a magic "__clone()" method.

This is very relevant, since the intrinsic definition of the prototype pattern says that all the objects spawned from the prototype will be created via a cloning process. Thus, that’s exactly the reason for declaring the "__clone()" method. Quite simple, right?

All in all, I defined two concrete classes for validating alphabetic and alphanumeric data. Considering that I’d like to extend the initial capacity of this data checking application, in the section to come I’m going to define a few additional prototype classes. They will be tasked with validating numbers and email addresses as well.

To see how these brand new classes will be built, click on the link below and keep reading. 

{mospagebreak title=Creating a few additional classes}

As you’ll certainly recall from the previous section, my intention here is to extend the functionality of this simple data validation application to make it capable of checking some additional incoming data, like numbers and email addresses.

Logically, these brand new classes will also declare the magic "__clone()" method that you saw earlier, so they can clone objects that might be needed by an application.

Now that I’ve clarified how these data checking classes are going to work, please take a minute and examine their respective signatures, which look like this:

// define concrete ‘NumbericValidatorPrototype’ class
class NumbericValidatorPrototype extends DataValidatorPrototype{
   public function validateData($inputData){
     if(!$inputData||!is_numeric($inputData)){
       return false;
     }
     return true;
   }
   public function __clone(){}
}

// define concrete ‘EmailValidatorPrototype’ class
class EmailValidatorPrototype extends DataValidatorPrototype{
   public function validateData($inputData){
     if(!$inputData||!preg_match("/.+@.+..+./",$inputData)||!
checkdnsrr(array_pop(explode("@",$inputData)),"MX")){
       return false;
     }
     return true;
   }
   public function __clone(){}         
}

As you can see, the prototype classes listed above implement the same business logic present in their predecessors concerning the declaration of the "__clone()" method. The definition of the method has been done deliberately, providing each validation class with the capacity to clone objects across a given application.

So far, so good. At this point hopefully you’ve grasped the functionality of each of the prototype classes defined previously. However, I’m pretty certain that you’re asking yourself…how can the prototype pattern be linked with the classes in question?

Well, to answer that smart question, in the section to come I’m going to develop a short script. It will show how multiple instances of the data checking classes that you have just learned can be put to work in conjunction.

Hopefully, after you see the example, you’ll have a more polished concept of how the prototype pattern functions.

To see how this practical example will be developed, please jump ahead and read the next few lines. I’ll be there, waiting for you.

{mospagebreak title=Creating an example}

As I said in the section that you just read, demonstrating the functionality of the prototype pattern, in this case implemented as part of a basic data validation application, is only a matter of building a simple PHP script that puts all the prototype classes to work together.

Basically, what I’m going to illustrate here is that it’s possible to work with a cloned instance of a specific validation object to check whether or not a particular input entry is considered offending. Naturally, the proper verification of incoming data will be performed by implementing the programmatic model dictated by the prototype pattern. In this way you can see more clearly how it works in this concrete case.

All right, now that I have explained the purpose of coding a hands-on example, please pay attention to the following code listing. It shows this handy pattern in action. Here it is:   

try{
   // create new ‘AlphabeticValidatorPrototype’ object
   $alphaPrototype=new AlphabeticValidatorPrototype();
   // clone prototype object
   $alphaVal=clone $alphaPrototype;
   // validate input data
   if(!$alphaVal->validateData(‘ABCDE’)){
     echo ‘Input data is not valid!’;
   }
   else{
     echo ‘Input data is valid!’;
   }

   /* displays the following:
   Input data is valid!
   */

   // create new ‘AlphanumericValidatorPrototype’ object
   $alphanumPrototype=new AlphanumericValidatorPrototype();
   // clone prototype object
   $alphanumVal=clone $alphanumPrototype;
   // validate input data
   if(!$alphanumVal->validateData(‘****12345***’)){
     echo ‘Input data is not valid!’;
   }
   else{
     echo ‘Input data is valid!’;
   }

   /* displays the following:
   Input data is not valid!
   */

   // create new ‘NumericValidatorPrototype’ object
   $numPrototype=new NumbericValidatorPrototype();
   // clone prototype object            
   $numVal=clone $numPrototype;
   // validate input data
   if(!$numVal->validateData(’12345′)){
     echo ‘Input data is not valid!’;
   }
   else{
     echo ‘Input data is valid!’;
   }

   /* displays the following:
   Input data is valid!
   */
}
catch(Exception $e){
   echo $e->getMessage();
   exit();
}

Wasn’t the above example easy to grasp? I bet it was! As you can see, the example first creates the corresponding prototype objects associated with every data checking class, and then uses the PHP built-in "clone()" method to create one instance of them. Next, these cloned instances perform a simple validation process on a bunch of primitive sample data, and finally an indicative message is displayed on the browser according to the results of this procedure.

A final note before you finish reading this article: I recommend that you use all of the prototype classes that I included here as a starting point for understanding more clearly how the prototype pattern works. Of course, you may want to introduce your own modifications to the classes or even better, develop your own functional examples.

As with many other topics associated specifically to PHP programming, it’s the best way to learn. 

Final thoughts

Unfortunately, we’ve come to the end of this series. I hope that all the examples shown in this group of articles will be useful enough to demonstrate in a friendly fashion how the prototype pattern can be implemented with PHP 5.

As you have seen, there are design patterns that are more unusual than others, and this is precisely the case with the prototype pattern. However, it doesn’t hurt to learn at least its basic principles, and eventually how it can be used to solve specific programming-related issues.

See you in the next PHP tutorial!

Google+ Comments

Google+ Comments