Working with Template Classes in PHP 5

A template class is a base class with some special abilities. First, it concretely implements one or more algorithms; second, it can determine which subclasses should use these algorithms. This article is the first part of a two-part series that introduces you to the basic concepts of this design pattern.

Introduction

Working with the object-oriented paradigm in PHP — and of course, other programming languages – implies having at least a basic understanding of its key concepts. A developer using this paradigm knows the intrinsic definition of a class, its properties and methods, and logically possesses a decent knowledge of the so-called big pillars of OOP, such as inheritance and polymorphism.

Naturally, if all of these important concepts are familiar to you, I should assume that you’ve been building your own PHP classes for a while, and that very often you find yourself creating a class API that hides all the complexity required for performing a number of predefined tasks.

However, there are times when a specific object-based PHP application needs to execute extremely complex processes. In most cases, these processes are encapsulated inside one or more methods of a class (or sometimes in many of them).

While this situation happens very frequently, it’s rather unusual to create classes that implement specific algorithms on top of the corresponding hierarchy. Most of the time, base classes only define the basic functionality of a group of objects, and the respective sub classes are responsible for implementing the business logic required to achieve specific tasks.

So, in which cases does the above situation occur? Well, at times it’s necessary to define a base class that concretely implements one or more algorithms. Additionally, this class may need to be capable of determining which subclasses should use these algorithms. In pattern-based jargon, this class is called a “template” and not surprisingly, it determines the programming model imposed by the homonymous pattern.

Indeed, template classes can be very interesting within the vast area of pattern-oriented programming. Over the course of this series, I’ll demonstrate how to implement this rather unusual design pattern by accompanying the corresponding theory with copious hands-on examples.

Hopefully this experience will be instructive. Let’s not waste more time in preliminaries; click on the link below to begin learning more about building template classes with PHP 5. Let’s get started!

{mospagebreak title=Creating a basic implementation of the template pattern}

Demonstrating the functionality of a template class is a process that can be achieved with only minor problems. First I’m going to define primarily two MySQL wrapping classes, which will be used for fetching database result sets. Then I’ll build a simple template class which will be responsible for setting up an algorithm for formatting these data sets.

Having explained how I plan to implement the template pattern with PHP, here are the pertinent signatures that correspond to the MySQL processing classes that I mentioned before: 

// define ‘MySQL’ class
class MySQL{
   private $conId;
   private $host;
   private $user;
   private $password;
   private $database;
   private $result;
   const OPTIONS=4;
   public function __construct($options=array()){
     if(count($options)!=self::OPTIONS){
       throw new Exception(‘Invalid number of connection
parameters’);
     }
     foreach($options as $parameter=>$value){
       if(!$value){
         throw new Exception(‘Invalid parameter
‘.$parameter);
       }
       $this->{$parameter}=$value;
     }
     $this->connectDB();
   }
   // connect to MySQL
   private function connectDB(){
     if(!$this->conId=mysql_connect($this->host,$this-
>user,$this->password)){
       throw new Exception(‘Error connecting to the
server’);
     }
     if(!mysql_select_db($this->database,$this->conId)){
       throw new Exception(‘Error selecting database’);
     }
   }
   // run query
   public function query($query){
     if(!$this->result=mysql_query($query,$this->conId)){
       throw new Exception(‘Error performing query
‘.$query);
     }
     return new Result($this,$this->result);
   }
}
// define ‘Result’ class
class Result{
   private $mysql;
   private $result;
   public function __construct(&$mysql,$result){
     $this->mysql=&$mysql;
     $this->result=$result;
   }
   // fetch row
   public function fetchRow(){
     return mysql_fetch_assoc($this->result);
   }
   // count rows
   public function countRows(){
     if(!$rows=mysql_num_rows($this->result)){
       throw new Exception(‘Error counting rows’);
     }
     return $rows;
   }
   // count affected rows
   public function countAffectedRows(){
     if(!$rows=mysql_affected_rows($this->mysql->conId)){
       throw new Exception(‘Error counting affected rows’);
     }
     return $rows;
   }
   // get ID form last-inserted row
   public function getInsertID(){
     if(!$id=mysql_insert_id($this->mysql->conId)){
       throw new Exception(‘Error getting ID’);
     }
     return $id;
   }
   // seek row
   public function seekRow($row=0){
     if(!is_int($row)||$row<0){
       throw new Exception(‘Invalid result set offset’);
     }
     if(!mysql_data_seek($this->result,$row)){
       throw new Exception(‘Error seeking data’);
     }
   }
}

As you can see, the two MySQL wrapping classes shown above are pretty familiar, since I used them in some of my previous PHP articles. However, the classes in question aren’t the primary objective of this tutorial, since I only plan to use them uniquely to fetch data from a MySQL database. That’s all.

Besides, as I expressed before, I’m going to create a template class to define a specific algorithm. The algorithm will be aimed at formatting the returned result sets. Sounds pretty simple, right?

Okay, now that the respective signatures of the previous MySQL wrapping classes are fresh in your mind, let’s learn how to build the template class previously mentioned. Keep reading, please.

{mospagebreak title=Building a simple template class}

According to the definition of the template pattern, there’s a base class that establishes a specific algorithm, which will also be used for the pertinent subclasses. As you can see, the definition sounds quite simple, but it may be a bit harder to grasp if you try to turn it into functional PHP code.

Therefore, bearing in mind this possible inconvenience, I’m going to create a sample template class. As you’ll see in a few moments, this class will set up a concrete algorithm for formatting MySQL result sets.

Having explained that, the signature that corresponds to this new template class is as follows: 

// define abstract ‘ResultTemplate’ class
abstract class ResultTemplate{
   // define template method (this is the algorithm setup by the base class)
   public final function displayFormattedResult($result){
     $output=”;
     // get formatted number of rows
     if($this->getFormattedNumRows($result)==NULL){
       throw new Exception(‘Number of rows not available’);
     }
     $output=$this->getFormattedNumRows($result).$this-
>getFormattedRows($result);
     return $output;
   }
   // this sets the generic method to format number of database rows
   public function getFormattedNumRows($result){
     return NULL;
   }
   // this sets the generic method to format database rows
   public function getFormattedRows($result){}
}

After examining the definition of the above “ResultTemplate” class, definitely you’ll have to agree with me that things are getting really interesting. As you can see, this template class has been defined as abstract, but it also presents an important method called “displayFormattedResult().”

Logically, the referenced method is responsible for setting up a specific algorithm for returning to calling code not only a string of formatted data sets, but the number of rows returned by the corresponding SELECT statement.

Besides, it’s worthwhile to mention here the existence of two other methods, named “getFormattedNumRows()” and “getFormattedRows()” respectively. These methods are used in conjunction to display the aforementioned formatted data sets.

Nonetheless, the signature of the previous “ResultTemplate” class demonstrates in a nutshell how the template pattern works, since this class defines an algorithm concretely (not abstractly), which will eventually be used by the respective child classes. Pretty simple to grasp, isn’t it?

Okay, at this stage you already learned how the prior template class was built, but there are a couple of missing elements in this schema. Since the template in question is seated on top of the hierarchy of classes, it’s necessary to create some subclasses so that you can see how they interact with each other.

As you may have guessed, these subclasses will be created in the section to come, so keep reading to learn more.

{mospagebreak title=Completing the model imposed by the template pattern}

As I expressed in the section that you just read, completing the programmatic model dictated by the template pattern in only a matter of deriving a couple of child classes from the base template class.

Of course, the reason for doing this is simply to understand how a concrete child class can use the specific formatting algorithm defined by the corresponding parent. In this case in particular, I’m going to derive only three subclasses from the base “ResultRemplate” class. Each of them will be tasked with applying different (X)HTML formats to a given MySQL data set.

Having explained how the respective child classes are going to work, please have a look at their respective definitions. Here they are:

// define concrete ‘ParagraphResultTemplate’ class
class ParagraphResultTemplate extends ResultTemplate{
   public function getFormattedNumRows($result){
     return ‘<h2>Number of rows: ‘.$result->countRows().’</h2>’;
   }
   public function getFormattedRows($result){
     $output=’<p>Record listing:</p>’;
     while($row=$result->fetchRow()){
       $tempOut=’<p>’;
       foreach($row as $field){
         $tempOut.=$field;
       }
       $tempOut.=’</p>’;
       $output.=$tempOut;
     }
     return $output;   
   }
}
// define concrete ‘DivResultTemplate’ class
class DivResultTemplate extends ResultTemplate{
   public function getFormattedNumRows($result){
     return ‘<h2>Number of rows: ‘.$result->countRows().’</h2>’;
   }
   public function getFormattedRows($result){
     $output=’<div>Record listing:</div>’;
     while($row=$result->fetchRow()){
       $tempOut=’<div>’;
       foreach($row as $field){
         $tempOut.=$field;
       }
       $tempOut.=’</div>’;
       $output.=$tempOut;
     }
     return $output;   
   }
}
// define concrete ‘DivResultTemplate’ class
class HeaderResultTemplate extends ResultTemplate{
   public function getFormattedNumRows($result){
     return ‘<h2>Number of rows: ‘.$result->countRows().’</h2>’;
   }
   public function getFormattedRows($result){
     $output=’<h3>Record listing:</h3>’;
     while($row=$result->fetchRow()){
       $tempOut=’<h3>’;
       foreach($row as $field){
         $tempOut.=$field;
       }
       $tempOut.=’</h3>’;
       $output.=$tempOut;
     }
     return $output;   
   }
}

As you can see, the three subclasses defined above use the formatting algorithm defined by the respective parent to return to client code a string of (X)HTML formatted database rows, and the number of records as well. However, none of these classes overrides the algorithm in question, since it’s always utilized as a template. Now, are you starting to grasp the logic that drives the template pattern? I’m sure you are!

So far, so good. At this time, you hopefully understand how this neat pattern does its business. If you’re anything like me, though, you want to see how it works in a concrete situation, right?

In the next section I’m going to develop a functional example. It will include all the template classes that were defined previously. Click on the below link and keep reading.

{mospagebreak title=Setting up a functional example}

As I stated in the previous section, below I included a hands-on example that demonstrates how all the template classes that were built previously can be utilized in a pretty useful way. The sample script fetches a simple result set from a sample “USERS” database table, and then uses the different templates to format this data set.

That being said, the corresponding code listing is as follows:

try{
   // connect to MySQL
   $db=new MySQL(array
(‘host’=>’host’,'user’=>’user’,'password’=>
‘password’,'database’=>’mydatabase’));
   $result=$db->query(‘SELECT * FROM users’);
   // instantiate ‘ParagraphResultTemplate’ object
   $parResultTemplate=new ParagraphResultTemplate();
   // display database formatted database result set
   echo $parResultTemplate->displayFormattedResult($result);
   /*
   displays the following (formatted as paragraphs):

   Number of rows: 10
   Record listing:
   1user1user1@domain.com
   2user2user2@domain.com
   3user3user3@domain.com
   4user4user4@domain.com
   5user5user5@domain.com
   6user6user6@domain.com
   7user7user7@domain.com
   8user8user8@domain.com
   9user9user9@domain.com
   10user10user10@domain.com
   */

            
   // instantiate ‘DivResultTemplate’ object
   $divResultTemplate=new DivResultTemplate();
   // run query against selected database
   $result=$db->query(‘SELECT * FROM users’);
   // display database formatted database result set
   echo $divResultTemplate->displayFormattedResult($result);
   /*
   displays the following (formatted as DIV elements):

   Number of rows: 10
   Record listing:
   1user1user1@domain.com
   2user2user2@domain.com
   3user3user3@domain.com
   4user4user4@domain.com
   5user5user5@domain.com
   6user6user6@domain.com
   7user7user7@domain.com
   8user8user8@domain.com
   9user9user9@domain.com
   10user10user10@domain.com
   */

            
   // instantiate ‘HeaderResultTemplate’ object
   $headerResultTemplate=new HeaderResultTemplate();
   // run query against selected database
   $result=$db->query(‘SELECT * FROM users’);
   // display database formatted database result set
   echo $headerResultTemplate->displayFormattedResult($result);
   /*
   displays the following (formatted as <h3> headers):

   Number of rows: 10
   Record listing:
   1user1user1@domain.com
   2user2user2@domain.com
   3user3user3@domain.com
   4user4user4@domain.com
   5user5user5@domain.com
   6user6user6@domain.com
   7user7user7@domain.com
   8user8user8@domain.com
   9user9user9@domain.com
   10user10user10@domain.com
   */
}
catch(Exception $e){
   echo $e->getMessage();
   exit();
}

As indicated above, all the template sub classes use the formatting algorithm defined by the parent to display a primitive MySQL data set using different (X)HTML tags. In the first case, database table rows are displayed as a group of paragraphs, while in the other two cases, the same rows are shown as a set of DIVs and <h3> headers respectively.

Feel free to modify all the classes shown here. In this way you can develop your own examples, and eventually acquire a better background in how the template pattern works. You’ll have a good time, trust me!

Final thoughts

In this first part of the series, I introduced the key concepts concerning the implementation of the template pattern with PHP 5. Also, you may have noticed that this pattern is rather unusual, particularly because the base template class has considerable control over how the respective subclasses must work.

In the next (and last) part of the series, I’ll be developing another instructive example where this pattern can be applied: the manipulation of file data via a template object. You won’t want to miss it!

Google+ Comments

Google+ Comments