Using the Observer Design Pattern with Static Data in PHP 5

In the vast terrain of object-oriented programming with PHP 5, working with static data members is an approach that provides developers with the capacity for building classes that are callable from outside the object context. It also lets them define properties that are shared by all the instances of those classes. If you’re interested in learning how to put this powerful feature to work for you, then you should start reading this series of articles now!

Introduction

Welcome to the last tutorial of the series "Handling Static Data with PHP 5." By using a step-by-step guide, this series walks you through working with static properties and methods in PHP 5, and also shows you how to combine this static data with some of the most popular design patterns, such as "Factory" and "Observer."

In the previous article, I went through the development of a basic example to demonstrate how the definition of a unique static property within a given class can facilitate the enchaining of different objects that belong to the class.

This rather primitive example showed how a bunch of user-related objects could increment the value of a specified static property each time a new one was properly instantiated. It demonstrated the principle that stands behind defining a class property as static. It should also be noticed that this basic example can be used as a starting point to develop more complex PHP applications that also use static data, since the core concepts remain the same, regardless of the size of the project being developed.

However, as I said before, defining a simple static property within a given PHP class to chain its different instances might seem extremely basic, not to mention that it’s hard to find a concrete application of this approach in the real world. Thus, keeping in mind this idea, in this last installment of the series I’ll show you how to use a static property, along with the programmatic model dictated by the observer pattern, to implement an expandable data validation system. This task might have an immediate application in a real situation.

Thus, having introduced the subject of this final part of the series, let’s move on together and see how to build the aforementioned data validation mechanism using a unique static property. Let’s get started!

{mospagebreak title=Handling user data via a single static property}

Before I continue demonstrating how useful a single static property can be in the context of object-oriented programming with PHP 5, I want to reintroduce the hands-on example developed in the preceding article of this series. This will make it fresh in your mind, which should really help if you want to reproduce the business logic implemented by it within your own PHP applications.

As you probably recall, the example in question illustrated how a group of instances belonging to the same originating class can be easily linked with each other by using a single static property. The signatures corresponding each of the sample classes used for that specific occasion looked like this:

// define abstract ‘User’ class – declares ‘$nextUserID’ property
static (it can be accessed by all the classes)
abstract class User{
   static public $nextUserID=1;
   public $userID;
   abstract public function __construct($fname,$lname,$email);
   abstract public function getFirstName();
   abstract public function getLastName();
   abstract public function getEmail();
   abstract public function getID();
}

// define ‘ForumUser’ class
class ForumUser extends User{
   public function __construct
($fname=’John’,$lname=’Doe’,$email=’john@domain.com’){
      if(!$fname){
         throw new Exception(‘Invalid First Name for forum
user.’);
      }
      if(!$lname){
         throw new Exception(‘Invalid Last Name for forum
user.’);
      }
      if(!$email||preg_match("/^.+@.+..+$/",$email)){
         throw new Exception(‘Invalid email address for forum
user.’);
      }
      $this->fname=$fname;
      $this->lname=$lname;
      $this->email=$email;
      $this->userID=self::$nextUserID++;
   }

   // get user’s First Name
   public function getFirstName(){
      return $this->fname;
   }

   // get user’s Last Name
   public function getLastName(){
      return $this->lname;
   }

   // get user’s email address
   public function getEmail(){
      return $this->email;
   }

   // get user’s ID
   public function getID(){
      return $this->userID;
   }
}
try{
   // create some forum user objects
   $user1=new ForumUser(‘Robert’,'Wilson’,'bob@domain.com’);
   $user2=new ForumUser(‘John’,'Smith’,'johnny@domain.com’);
   $user3=new ForumUser(‘Susan’,'Jackson’,'suse@domain.com’);
   $user4=new ForumUser(‘Mary’,'King’,'mary@domain.com’);

   // display information on first forum user
   echo ‘<h2>Data for first forum user is as following:</h2>’;
   echo ‘<p>First Name: ‘.$user1->getFirstName().’</p><p>Last
Name: ‘.$user1->getLastName().’<p/><p>Email address: ‘.$user1-
>getEmail().’</p><p>User ID: ‘.$user1->getID().’</p>’;
   /*
   displays the following:
   
Data for first forum user is as following:
   First Name: Robert
   Last Name: Wilson
   Email address: bob@domain.com
   User ID: 1
   */   

   // display information on second forum user
   echo ‘<h2>Data for second forum user is as following:</h2>’;
   echo ‘<p>First Name: ‘.$user2->getFirstName().’</p><p>Last
Name: ‘.$user2->getLastName().’<p/><p>Email address: ‘.$user2-
>getEmail().’</p><p>User ID: ‘.$user2->getID().’</p>’;
   /*
   displays the following:

Data for second forum user is as following:
   First Name: John
   Last Name: Smith
   Email address: johnny@domain.com
   User ID: 2
   */

   // display information on third forum user
   echo ‘<h2>Data for third forum user is as following:</h2>’;
   echo ‘<p>First Name: ‘.$user3->getFirstName().’</p><p>Last
Name: ‘.$user3->getLastName().’<p/><p>Email address: ‘.$user3-
>getEmail().’</p><p>User ID: ‘.$user3->getID().’</p>’;
   /*
   displays the following:

Data for third forum user is as following:
   First Name: Susan
   Last Name: Jackson
   Email address: suse@domain.com
   User ID: 3
   */

   // display information on last forum user
   echo ‘<h2>Data for last forum user is as following:</h2>’;
   echo ‘<p>First Name: ‘.$user4->getFirstName().’</p><p>Last
Name: ‘.$user4->getLastName().’<p/><p>Email address: ‘.$user4-
>getEmail().’</p><p>User ID: ‘.$user4->getID().’</p>’;
   /*
   displays the following:

Data for last forum user is as following:
   First Name: Mary
   Last Name: King
   Email address: mary@domain.com
   User ID: 4
   */
}
catch(Exception $e){
   echo $e->getMessage();
   exit();
}

As you can see, the previous sample classes implement a primitive application for displaying some basic data about a few fictional users, such as their first and last names, along with their email addresses. However, the most interesting thing to note here is the utilization of a single static "$nextUserID" property, which is used by all the instances of the originating "ForumUser" class to increment the ID of the next user. Indeed, this implementation of a given static property shows in a nutshell its remarkable functionality, particularly when it comes to enchaining several instances of a specific class.

So far, so good. At this stage, you hopefully grasped the logic that drives the above hands-on example. So let’s take a look at another case where the use of a single static property can be really handy.

In this case, I’ll show you how to build an expandable data validation system utilizing a basic static property in conjunction with the programmatic model dictated by the popular Observer design pattern.

Want to see how this will be achieved? Jump ahead and read the next few lines.

{mospagebreak title=Using a static property with the Observer pattern}

According to the concepts expressed in the previous section, my purpose here is simply to illustrate how a static property can be used to tackle a real world problem. I’m going to build a basic data validation mechanism for verifying common input types, like alphabetic and numeric data, as well as email addresses.

Nonetheless, and here is where things get really interesting, the core logic of the system described above will be implemented via an observer class. As you might guess, this class will use a static property to control the validity of all the inputted data.

Now that I have explained how this validation system will work, please take a look at the definition of the following classes, which are responsible for the correct implementation of the system in question:

// define ‘Observer’ class
class Observer{
   static public $errors=0;
   static public function checkData(){
      if(!self::$errors){
         return true;
      }
      return false;
   }
}

// define ‘AlphaValidator’ class
class AlphaValidator extends Observer{
   public function validate($data){
      if(!preg_match("/^[a-zA-Z ]+$/",$data)){
         self::$errors++;
      }
   }
}

class NumberValidator extends Observer{
   public function validate($data){
      if(!is_numeric($data)){
         self::$errors++;
      }
   }
}

class EmailValidator extends Observer{
   public function validate($data){
      if(!preg_match("/^.+@.+..+$/",$data)){
         self::$errors++;
      }
   }
}

As show above, I coded some basic PHP classes, which in conjunction implement the so-called observer design pattern. Logically, in this particular case, the functionality provided by the pattern is utilized to validate basic types of input data. This process is performed by a bunch of specific data checking classes.

However, you should notice that on top of this validation system, there’s an observer class that uses a static property called "$errors" to determine whether any failures occurred when validating specific types of data. Of course, since this property is also shared by all the validation classes, its value is incremented each time a specific input data is considered invalid. In this case it "notifies the observer" that an error was triggered when validating a certain input. Pretty simple to grasp, right?

All right, having explained the programming logic that drives the previous data checking system, it’s time to move on and code an illustrative example. In this final example, all of the above classes will be put to work in conjunction, in this manner showing the actual functionality of the system.

As you might guess, this practical demonstration will be done in the following section, thus click on the below link and keep reading.

{mospagebreak title=Putting the data checking system to work}

As I stated in the section that you just read, below I coded several hands-on examples that illustrate how the data validation system that you learned earlier works to check some basic input data.

Here are the mentioned examples, along with their corresponding outputs:

try{
   // create observer object
   $observer=new Observer;

   // create validator objects
   $alphaVal=new AlphaValidator;
   $numVal=new NumberValidator;
   $emailVal=new EmailValidator;

   // validate some basic input data
   $alphaVal->validate(‘This is a valid input string’);
   $numVal->validate(‘This is not a number’);
   $emailVal->validate(‘user@domain.com’);
   if(!Observer::checkData()){
      echo ‘Inputted data is not valid’;
   }
   else{
      echo ‘Inputted data is valid’;
   }

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

//*******************************************
try{
   // create observer object
   $observer=new Observer;

   // create validator objects
   $alphaVal=new AlphaValidator;
   $numVal=new NumberValidator;
   $emailVal=new EmailValidator;

   // validate some basic input data
   $alphaVal->validate(‘This is a valid input string’);
   $numVal->validate(1);
   $emailVal->validate(‘user@domain’);
   if(!Observer::checkData()){
      echo ‘Inputted data is not valid’;
   }
   else{
      echo ‘Inputted data is valid’;
   }

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

//*******************************************
try{
   // create observer object
   $observer=new Observer;

   // create validator objects
   $alphaVal=new AlphaValidator;
   $numVal=new NumberValidator;
   $emailVal=new EmailValidator;

   // validate some basic input data
   $alphaVal->validate(’1 is a number’);
   $numVal->validate(1234);
   $emailVal->validate(‘user@domain.com’);
   if(!Observer::checkData()){
      echo ‘Inputted data is not valid’;
   }
   else{
      echo ‘Inputted data is valid’;
   }

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

//*******************************************
try{
   // create observer object
   $observer=new Observer;

   // create validator objects
   $alphaVal=new AlphaValidator;
   $numVal=new NumberValidator;
   $emailVal=new EmailValidator;

   // validate some basic input data
   $alphaVal->validate(‘S’);
   $numVal->validate(1234);
   $emailVal->validate(‘user@domain.com’);
   if(!Observer::checkData()){
      echo ‘Inputted data is not valid’;
   }
   else{
      echo ‘Inputted data is valid’;
   }

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

Weren’t all the above code samples easy to follow? I’m sure they were. As you can see, the previous data checking mechanism uses the programmatic model imposed by the observer pattern, along with a single static property to validate different types of inputted data. Considering that coding the prior classes may take only a few minutes, and the system’s capacity to be expanded upon, you’ll have to agree with me that using static properties and methods with PHP 5 brings many benefits. 

Final thoughts

Sadly, we’ve come to the end of this series. Hopefully, after reading all these tutorials, you’ll be better prepared to start using static data with your own PHP-driven applications.

See you in the next PHP tutorial!

[gp-comments width="770" linklove="off" ]
antalya escort bayan antalya escort bayan