Handling File Data with the Facade Pattern in PHP 5

Are you interested in learning the foundations of different structural patterns in PHP 5? If your answer is affirmative, then you should start reading this article immediately! Welcome to the last installment of the series “Introducing the Facade Pattern in PHP 5.” In two consecutive articles, this series shows you how to create and use facade classes in PHP-based development environments.

Introduction

As you know, PHP 5 allows you to create web applications that implement a diverse range of design patterns, logically including that one called “facade.” If you’ve not yet read the first part of this series and don’t know what this pattern is about, then let me offer you a brief introduction.

Essentially, in the facade pattern a class is created in such a way that it’s able to hide all the complexity inherent to a given mechanism, in order to perform a specific task. This mechanism (usually comprised of one or more classes) is completely independent from the calling class, and knows nothing about it. As you might guess, even though this theoretical definition may sound a bit complex, the truth is that creating facade classes with PHP 5 is an easy process.

To clarify possible questions on how this pattern works, in the first part of the series I worked in a step-by-step format to define a simple façade class. The class was capable of compressing a diverse range of contents, including all the source code created by a web page generator class.

The most important part of this facade class was logically the one related to hiding all the complexity involved in compressing the (X)HTML output of different web documents by using a pair of additional classes. In accordance with the logic dictated by the pattern, these supporting classes were entirely independent of the facade. They were tasked only with compressing any number of input strings passed as parameters to a specific method.

Now that you hopefully recalled the topics covered in the preceding article, it’s time to pay attention to the subject of this one. I’m going to continue demonstrating the application of the facade pattern, this time by developing yet another illustrative application. It will take care of processing the contents of a selected data file in different ways.

So how does a facade class fit into this schema? Start reading to find out!

{mospagebreak title=Using the facade pattern to handle file data}

As I said in the introduction, before I proceed to create a facade class I’m going to define a simple yet efficient file processing class, which, as you’ll see in a moment, will be capable of reading and writing data to a given text file.

However, once the file handling class has been created, I’m going to show you how it can be used in tandem with the facade class in question. So, for the moment, I suggest you pay strong attention to the definition for the class, which looks like this: 

// define ‘FileProcessor’ class
class FileProcessor{
    private $dataFile;
    private $fileData;
    public function __construct($dataFile=’datafile.txt’,
            $data=’This string of data will be saved to file!’){
      if(!file_exists($dataFile)){
        throw new Exception(‘Invalid path for data file!’);
      }
      $this->dataFile=$dataFile;
      if(!data){
        throw new Exception(‘Invalid data to be saved on data file!’);
      }
      $this->data=$data;
    }
    // read data from file
    public function readData(){
      if(!$content=file_get_contents($this->dataFile)){
        throw new Exception(‘Error reading data from data file!’);
      }
      return $content;
    }
    // write data to 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!’);
      }
      fclose($fp);
    }
}

As shown above, the logic implemented by the “FileProcessor” class is indeed easily followed. Basically, all this class does is save an input string to a specified text file, via the respective “writeData()” method, and write the string to the same file, in this particular case by the means of “readData().” So far there’s nothing unexpected, right?

Based upon the functionality offered by this simple file processing class, below I listed a short script, which exemplifies the use of this class. Have a look at the following code sample, please:

// example using ‘FileProcessor’ class
try{
   // instantiate new ‘FileProcessor’ object
   $fileProc=new FileProcessor();
   // write data to text file
   $fileProc->writeData();
   // read and display data from text file
   echo $fileProc->readData();
}
catch(Exception $e){
   echo $e->getMessage();
   exit();
}

In this case, the above script shows clearly how the “FileProcessor” class that I created a few lines above can be used in a useful way. As you can see, the previous code snippet first instantiates a new file processor object, then writes a default input string to the specified data file, and finally displays this data on the browser.

Of course, this example would be rather incomplete if I didn’t show you the corresponding output produced by previous script, which is as follows:

‘This string of data will be saved to file!

All right, at this point I’m quite sure that you understand how the “FileProcessor” class does its thing. I assume you’re also intrigued by how this class can be an important piece of the facade pattern. Therefore, in the next section I’m going to create a facade class which will be capable of applying different formats to an inputted string, including all the data read by the file processing class that was covered before.

To see how this entirely new facade class will be defined, go ahead and read the following section. I’ll be there, waiting for you.

{mospagebreak title=Applying the facade pattern to a string processor}

Undoubtedly, one of the best ways to understand more clearly the logic that belongs to the facade pattern consists of defining a class that implements the referenced pattern in a friendly format. In this case, I followed this approach faithfully, and created the class below. It is named “ProcessContentFacade,” and its signature is as follows:

// define ‘ProcessContentFacade’ class
class ProcessContentFacade{
    public static function processContent($content){
      // reverse content
      $reversedContent=StringToReverse::reverseString($content);
      // uppercase content
     
$uppercasedContent=StringToUppercase::
                              uppercaseString($reversedContent);
     
return $uppercasedContent;
    }
}

As you’ll realize, the previous facade class is capable of performing a few handy formatting tasks, like uppercasing and reversing a given input string in turn. However, the most remarkable aspect concerning the signature of this class rests on the approach followed for executing these operations. They’re performed by using two additional classes, called “StringToReverse” and “StringToUppercase” respectively.

The corresponding definitions for these additional classes are shown below. Please take a look at them:

// define ‘StringToReverse’ class
class StringToReverse{
    // reverse string
    public static function reverseString($inputString){
      if(!$inputString){
        throw new Exception(‘Input string must not be empty!’);
      }
      return strrev($inputString);
    }
}
// define ‘StringToUppercase’ class
class StringToUppercase{
    // uppercase string
    public static function uppercaseString($inputString){
      if(!$inputString){
        throw new Exception(‘Input string must not be empty!’);
      }
      return strtoupper($inputString);
    }
}

Here, it’s clear to see how the facade pattern is appropriately implemented: on one hand you have a specific class that hides the process for reversing and uppercasing an inputted string; on the other hand, there are two classes that are completely independent from each other, and besides, they don’t know anything about the class that called them. Is this a programmatic model of the facade pattern? Of course it is!

Okay, I have to admit that I got caught up for a moment. But seriously, the three classes that you saw before demonstrate how easy it is to implement the facade pattern with PHP 5.

Now that you have properly grasped the logic followed by this group of classes, it’s time to move forward. We’ll see how the file processor that I built in the beginning of this article can be incorporated into one single example. In this way we’ll complete the implementation of the facade pattern.

As you can see, all the pieces of this puzzle are starting to fit together. If you want to see how this journey ends, click on the link below and read the final section of this tutorial. We’re almost done!

{mospagebreak title=Putting all the classes to work together}

In this final section of the article, I’d like to show you how all the classes that I created previously can be put to work conjunctly. In this manner I’ll demonstrate the neat functionality offered by the already familiar facade pattern.

Below I set up a short example. It shows the output generated by the pertinent file processing class, and the different results displayed by the respective facade class.

Having said that, here the complete source code that corresponds to the hands-on example in question:

// example using ‘ProcessContentFacade’ class
try{
   // instantiate new ‘FileProcessor’ object
   $fileProc=new FileProcessor();
   // write data to file
   $fileProc->writeData();
   // read and display file data before using 
   // ‘ProcessContentFacade’ class
   echo $fileProc->readData();
   /*
   displays the following:
   This string of data will be saved to file!
   */
   // reverse and uppercase file data by using
   // ‘ProcessContentFacade’ class
   $processedData=ProcessContentFacade::
processContent($fileProc->readData());
   echo $processedData;
   /* displays the following:
   !ELIF OT DEVAS EB LLIW ATAD FO GNIRTS SIHT
   */
}
catch(Exception $e){
   echo $e->getMessage();
   exit();
}

Without a doubt, after studying the above example, you’ll realize that implementing the facade pattern with PHP 5 is indeed a straightforward process that can be performed with only minor troubles. As usual, feel free to incorporate your own modifications to all the classes that were shown in this article. Doing so will help you acquire a more intimate grounding in how this design pattern works. Happy coding!

Final thoughts

Sadly, this is the end of this series. Over the course of these two tutorials, I introduced the fundamentals of how to apply the facade pattern in PHP 5. If you spend some time and practice with the examples that I provided you here, I’m pretty certain that you’ll end up having a reasonable experience on this pattern in particular.

See you in the next PHP tutorial!

[gp-comments width="770" linklove="off" ]

chat