Processing File Data with Template Classes in PHP 5

If you’re looking for a friendly guide on how to implement the template design pattern with PHP 5, then this group of articles might be what you need. Welcome to the final installment of the series that began with "Working with template classes in PHP 5." As the title indicates, this series steps you through creating template classes in PHP-controlled development environments, and also shows you how to use this rather uncommon pattern in real-world situations.

Introduction

Stepping back for a moment to the preceding article of the series, you’ll remember that I demonstrated via a step-by-step process not only how to build a template class in PHP, but how to use it in conjunction with a few handy subclasses. Indeed, the purpose of developing the programmatic model dictated by the pattern was simply to create a group of interrelated classes, which were capable of applying different (X)HTML formatting tags to a given MySQL result set.

Of course, if you already understand how the aforementioned example worked, you shouldn’t have major problems grasping all the code samples that I plan to include in this final article of the series. Why do I say this? Well, to be frank, I believe that the best way to understand the logic of a given pattern is by demonstrating its implementation with numerous hands-on examples.

Therefore, taking into account this important premise, over the course of this last tutorial I’m going to provide you with a few more examples of how to build template classes with PHP 5. More specifically speaking, what you’re going to learn here will be how to create a set of template objects that will control the visual appearance of data fetched from different files.

Logically, according to the definition imposed by the template pattern, there will be a base class responsible for setting up a specific algorithm via one of its methods, and other subclasses that will use the algorithm in question.

All right, having established the objective of this article, it’s time to move on and keep learning how to build template classes in PHP 5. Let’s begin now!

{mospagebreak title=Building a basic file processing class}

A good point to start demonstrating an approachable implementation of the template pattern consists of defining a basic file processing class, which will be used later on by a template object to display contents fetched from a specific target file.

As you’ll see, the file contents will be displayed either in (X)HTML and XML format or as an uppercased string, depending on which template class will be used for this purpose. So far there’s nothing unexpected, right?

Now that you know the reasons for using a template object, please pay attention to the signature of the file processing class. It looks like this:

// define ‘FileProcessor’ class
class FileProcessor{
   private $dataFile;
  
private $data;
  
public function __construct($dataFile=’default_file.txt’,
               $data=’This is the default data.’){
    
if(!file_exists($dataFile)){
      
throw new Exception(‘A valid data file must be
provided!’);
     
}
    
if(!is_string($data)){
      
throw new Exception(‘File data must be a string!’);
    
}
    
$this->dataFile=$dataFile;
    
$this->data=$data;
  
}
  
// write data to target file
  
public function writeData(){
    
if(!$fp=fopen($this->dataFile,’w')){
      
throw new Exception(‘Error opening data file!’);
    
}
    
if(!fwrite($fp,$this->data)){
      
throw new Exception(‘Error writing data to file!’);
    
}
    
flose($fp);
  
}
  
// read data from target file
  
public function readData(){
    
if(!$contents=file_get_contents($this->dataFile)){
      
throw new Exception(‘Error reading from data file!’);
    
}
    
return $contents;
  
}
  
// get size of data file
  
public function getFileSize(){
    
if(!$size=filesize($this->dataFile)){
      
throw new Exception(‘Error retrieving size of data
file!’); 
    
}
    
return $size;
  
}
}

As illustrated above, the logic followed by the previous "FileProcessor" class is indeed very easy to understand. In crude terms, all that this class does is read and write data to a specified target file, in addition to determining the size of this file by using its simple "getFileSize()" method.

However, as you might have guessed, the previous class isn’t the main objective of this tutorial at all. As I said before, I’m going to use an instance of it, so it can be adequately processed by a template object. Sounds pretty simple, doesn’t it?

Of course, as you know, the signature of this template class remains undefined, so if you want to see how the template in question will look, please click on the link below and keep reading.

{mospagebreak title=Creating a simple template class}

In consonance with the concepts that I deployed in the previous section, after defining the file processing class that you saw before, the next step to take here involves building the structure of a template class. The class will be responsible of setting up a base algorithm for displaying some data fetched from a specified target file.

However, I think that the true functionality of this template class will be understood best if I first show you its corresponding signature. It is as follows: 

// define abstract ‘FileTemplate’ class
abstract class FileTemplate{
   // this method setup the generic algorithm to format file
contents
  
public final function displayFormattedFileContents
($fileProcessor){
    
$output=”;
     if($this->getFileSize($fileProcessor)==NULL){
      
throw new Exception(‘Size of data file could not be
retrieved!’);
    
}
    
$output.=$this->getFileSize($fileProcessor).$this-
>getFormattedFileContents($fileProcessor);
    
return $output;
  
}
  
// this method setup the generic algorithm to get the size of
data file
  
public function getFileSize($fileProcessor){
    
return NULL;
  
}
  
// this method has not implementation (implemented in the
subclasses)
  
public function getFormattedFileContents(){}
}

If you examine the definition that corresponds to the above class, I’m pretty certain that you’ll grasp easily the logic that stands behind the template pattern. As you can see, this abstract template class presents a method called "displayFormattedFileContents()," which obviously is its workhorse, since it establishes a formatting algorithm that will be applied to all data fetched from a specific file.

Also, it’s valid to notice here the existence of two additional methods. These are used internally by the template class to implement the formatting algorithm. In this particular case, the first method, that is the one called "getFileSize()," logically is tasked with returning to calling code the size of the target file from which the data is retrieved, while the second one, named "getFormattedFileContents()," defines a generic interface for displaying file contents as (X)HTML, XML or an uppercased string. Quite simple, isn’t it?

Well, at this time you already saw how the previous template class looks, so what’s the next thing to do? As you saw, the "getFormattedFileContents()" method that you learned before doesn’t have a concrete definition, which means that it must be implemented by the corresponding subclasses.

Therefore, the respective signatures of these child classes will be shown in the next section. Jump ahead and keep reading to find out how they will look.

{mospagebreak title=Building a few simple subclasses}

As you’ll certainly recall from the previous section, the template class that you saw presented a method called "getFormattedFileContents()," which doesn’t have a concrete implementation. Naturally, this fact implies that the method in question must be explicitly defined by all the subclasses derived from the corresponding parent.

Therefore, I’m going to build three different child classes. These classes will be tasked with displaying the data fetched from a given file in diverse formats. With reference to this, the first class will return file contents as an uppercased string, while the other two will show this data in (X)HTML and XML formats respectively.

Having explained how these subclasses are going to work, you can now take a look at their respective signatures. They look like this:

// define concrete ‘UppercasedFileTemplate’ class
class UppercasedFileTemplate extends FileTemplate{
  
public function getFileSize($fileProcessor){
    
return ‘SIZE OF DATA FILE IS :’.strtoupper($fileProcessor-
>getFileSize()).’ BYTES’;
  
}
  
public function getFormattedFileContents($fileProcessor){
    
return ‘CONTENTS OF DATA FILE ARE AS FOLLOWS :’.strtoupper
($fileProcessor->readData());
  
}
}

// define concrete ‘HTMLFileTemplate’ class
class HTMLFileTemplate extends FileTemplate{
  
public function getFileSize($fileProcessor){
    
return ‘<html><head><title>Testing Template Pattern</title></head><body><h2>Size of data file is:
‘.$fileProcessor->getFileSize().’ bytes</h2>’;
  
}
  
// display file contents as HTML
  
public function getFormattedFileContents($fileProcessor){
    
$output=’<p>Contents of data file are as follows :</p>’;
    
$contents=explode("n",$fileProcessor->readData());
    
foreach($contents as $line){
      
$output.=’<p>’.$line.’</p>’;
    
}
    
$output.=’</body></html>’;
    
return $output;
  
}
}

// define concrete ‘XMLFileTemplate’ class
class XMLFileTemplate extends FileTemplate{
  
public function getFileSize($fileProcessor){
    
return ‘<?xml version="1.0" encoding="iso-8859-1"?><contents><size>Size of data file is: ‘.$fileProcessor-
>getFileSize().’ bytes</size>’;
  
}
  
// display file contents as XML
  
public function getFormattedFileContents($fileProcessor){
    
$output=”;
    
$contents=explode("n",$fileProcessor->readData());
    
foreach($contents as $line){
      
$output.=’<data>’.$line.’</data>’;
    
}
    
$output.=’</contents>’;
    
return $output;
  
}
}

As you’ll possibly agree, the pertinent structures of the above three subclasses are quite simple to understand. As you can see, each one of them accepts an instance of the file processor class that was shown in a previous section, and implements concretely the "getFormattedFileContents()" method that you learned before.

Of course, the output format applied to the data retrieved from a specified file will depend on the subclass being instantiated, certainly a fact that can be seen clearly when examining each of the subclasses listed above.

Okay, now that you know how the previous child classes look, the programmatic schema imposed by the template pattern should be familiar to you, since on top of the hierarchy there’s a template class that defines a specific formatting algorithm, which is implemented by the respective subclasses.

Nonetheless, I believe that the functionality of the template pattern is better appreciated by a functional example. In the upcoming section I’m going to build a simple PHP script where all the previous template classes will be put to work in conjunction.

Want to see how this script will be created? Keep reading, please.

{mospagebreak title=Seeing the template pattern in action}

As I expressed in the section that you just read, below I included a short script which demonstrates in a friendly fashion the functionality of all the classes that I defined earlier. Also, the script in question assumes that there’s a sample "default_file.txt" file that contains the following data:

This is line 1 of data file
This is line 2 of data file
This is line 3 of data file
This is line 4 of data file
This is line 5 of data file
This is line 6 of data file
This is line 7 of data file
This is line 8 of data file
This is line 9 of data file
This is line 10 of data file

Having clarified that point, please examine the below example along with the different outputs that it generates:

try{
 
// create new ‘FileProcessor’ object
 
$fileProc=new FileProcessor();
 
// create new ‘UppercasedFileTemplate’ object
 
$upperFileTemplate=new UppercasedFileTemplate();
 
// display file contents as uppercased string
  // echo $upperFileTemplate->displayFormattedFileContents
($fileProc);

  /*
 
displays the following:

  SIZE OF DATA FILE IS :280 BYTES
 
CONTENTS OF DATA FILE ARE AS FOLLOWS :
 
THIS IS LINE 1 OF DATA FILE
 
THIS IS LINE 2 OF DATA FILE
 
THIS IS LINE 3 OF DATA FILE
 
THIS IS LINE 4 OF DATA FILE
 
THIS IS LINE 5 OF DATA FILE
 
THIS IS LINE 6 OF DATA FILE 
  THIS IS LINE 7 OF DATA FILE
 
THIS IS LINE 8 OF DATA FILE
 
THIS IS LINE 9 OF DATA FILE
 
THIS IS LINE 10 OF DATA FILE
 
*/

  // create ‘HTMLFileTemplate’ object
 
$htmlFileTemplate=new HTMLFileTemplate();
 
// display file contents as HTML
 
//echo $htmlFileTemplate->displayFormattedFileContents
($fileProc);

  /* displays the following (formatted as HTML)

  Size of data file is: 280 bytes
 
Contents of data file are as follows :
 
This is line 1 of data file
 
This is line 2 of data file
 
This is line 3 of data file
 
This is line 4 of data file
 
This is line 5 of data file
 
This is line 6 of data file
 
This is line 7 of data file
 
This is line 8 of data file
 
This is line 9 of data file
 
This is line 10 of data file
 
*/

  // create ‘XMLFileTemplate’ object
 
$xmlFileTemplate=new XMLFileTemplate();
 
// display file contents as XML
 
header(‘Content-Type: text/xml’);
 
echo $xmlFileTemplate->displayFormattedFileContents
($fileProc);

  /* displays the following: (formatted as XML)

  <contents>
 
<size>Size of data file is: 280 bytes</size>
 
<data>This is line 1 of data file</data>
 
<data>This is line 2 of data file</data>
 
<data>This is line 3 of data file</data>
 
<data>This is line 4 of data file</data>
 
<data>This is line 5 of data file</data>
 
<data>This is line 6 of data file</data>
 
<data>This is line 7 of data file</data>
 
<data>This is line 8 of data file</data>
 
<data>This is line 9 of data file</data>
 
<data>This is line 10 of data file</data>
 
</contents>
 
*/
}
catch(Exception $e){
  echo $e->getMessage();
 
exit();
}

As you can see, the above example demonstrates quite clearly how the template pattern works. All the template subclasses instantiated previously use the algorithm defined by the respective parent to display, in a specific format, data fetched from a specific file.

One last note before I finish this tutorial: as usual, feel free to tweak the source code of all the classes included here, so you can introduce improvements and acquire a better understanding on how the template pattern works.

Final thoughts

That’s all for now. In this two-part series, hopefully you expanded your existing background on pattern-based programming with PHP, by learning a new one. Perhaps building template classes won’t change your developer life forever, but it’ll help you to have a more solid knowledge of how this pattern works.

See you in the next PHP tutorial!

Google+ Comments

Google+ Comments