Working with MySQL Result Sets and the Decorator Pattern in PHP

If you’re one of those avid PHP developers who wants to learn how to apply the decorator design pattern within your Web applications, then this group of articles might be quite appealing to you. Welcome to the second part of the series “Using the Decorator pattern with PHP.” Comprised of two parts, this series walks you through the core concepts of using this pattern in PHP, and shows you its practical edge with numerous hands-on examples.

Introduction

For those readers that just found this article after doing some research on the Web, let me tell you that in the previous tutorial, I explained the foundations of the decorator pattern in PHP, and developed an easy-going example to show how it works. Basically, this pattern will allow you to add more functionality to an existing class, without having to change its original structure.

As I mentioned right at the beginning of this series, this result also might be achieved by using inheritance and creating some subclasses from a base class. However, depending on the context where an application will be developed, there are times when it’s preferable to work with objects of different types, instead of using child objects that belong to the same family.

Whatever reasons you have for using objects of different types, the fact is that creating decorator objects in PHP is admittedly easy. In this second article, I’ll take advantage of this handy feature by demonstrating how the decorator pattern can be used in a real situation that you probably tackle very often: processing MySQL result sets.

Definitely, the pattern in question can be used for generating different types of outputs (or views) based on a returned result set, by using a few decorator classes that I’ll define in the course of this tutorial. Hopefully, when you finish reading these lines, you should have a clear idea of how to include decorator classes in your object-based PHP applications.

Are you ready to learn more about the decorator pattern? Okay, let’s get started!

{mospagebreak title=Handling MySQL result sets}

In order to demonstrate how the decorator pattern can be used for generating different outputs based on the same MySQL result set, first I’ll list two MySQL processing classes, which will be used for returning data sets from a sample database. So, having said that, below are the signatures of this pair of classes:

// define MySQL class
class MySQL{
    private $conId;
    private $host;
    private $user;
    private $password;
    private $database;
    public function __construct($options=array()){
        if(count($options)<4){
            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 database
    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 insert ID
    public function getInsertID(){
        if(!$id=mysql_insert_id($this->mysql->conId)){
            throw new Exception(‘Error getting ID’);
        }
        return $id;
    }
    // seek rows
    public function seekRow($row=0){
        if(!int($row)||$row<0){
            throw new Exception(‘Invalid result set offset’);
        }
        if(!mysql_data_seek($this->result,$row)){
            throw new Exception(‘Error seeking data’);
        }
    }
    // return result set
    public function getResult(){
        return $this->result;
    }
}

The two classes listed above shouldn’t be difficult to understand at all, since I used them as examples in previous PHP-related tutorials. In simple terms, these classes allow you to connect to MySQL and return result sets from a selected database, which is very convenient for my purpose of demonstrating how some decorator classes can process a specific result set.

So far, so good. At this stage, I have provided you with a couple of straightforward MySQL processing classes. Now, it’s time to pay strong attention to the next few lines, where I’ll be developing some decorator classes to generate different outputs from a given MySQL data set.

Want to see how this will be done? Then please read the following section.

{mospagebreak title=Retrieving MySQL result sets without changing the original class}

Essentially, what I plan to do here is generate different output formats, based on the same MySQL result set, by using several decorator classes. However, I have to admit a nearly identical result might be achieved by aggregating some additional methods to the “Result” class that you saw before. Why not do it that way?

Well, I have a good reason for not doing this. I want to keep the scope of the “Result” class limited to handling result sets, without contaminating its source code with methods that deal with formatting them.

As you can see, here the reward is double: you work with completely independent objects, while using decorator classes to apply specific formats to MySQL result sets. Sounds good, doesn’t it?

Having justified the real need for creating decorator classes, I’ll show you the first one, which I call “ResultDecorator.” Its definition is as follows:

class ResultDecorator{
    private $resultObj;
    public $resultSet;
    // pass in ‘Result’ object to the constructor
    public function __construct(Result $resultObj){
        $this->resultObj=$resultObj;
        // get result set without modifying the original object
        $this->resetResult();
    }
    private function resetResult(){
        $this->resultSet=$this->resultObj->getResult();
    }
}

Regarding the brand new class listed above, you’ll see that it takes up an object of type “Result” and assigns it as a class property. It additionally uses its “resetResult()” method to get a result set, after running a SELECT query.

So, recapitulating, I created a new class, which takes a result set from the respective “Result” class without modifying its original structure. That’s exactly what a decorator class is about! We’re on the right track now, since from this point onward, building decorator classes that generate different outputs from the same result set is a straightforward process.

After having defined the handy “ResultDecorator” class that you learned before, it’s time to go one step further and start creating the pertinent decorator classes, aimed at rendering different output formats, based on the same MySQL result set.

That’s exactly the subject of the upcoming section, therefore click on the link that appears below and keep on reading.

{mospagebreak title=Defining multiple decorator classes}

As I said previously, having a result set decorator class which behaves like a bridge between the original class and further ones makes constructing new decorator classes a simple process.

To demonstrate the veracity of my concepts, I’ll begin creating some simple decorator classes, where each of them is tasked with taking a MySQL result set and returning it in a different format. The list of these new classes starts with the “StringResultDecorator” class, which has been defined as follows:

class StringResultDecorator extends ResultDecorator{
    private $resultDecorator;
    // pass ‘ResultDecorator’ object to the constructor
    public function __construct(ResultDecorator $resultDecorator){
        $this->resultDecorator=$resultDecorator;
    }
    // display result set as formatted string
    public function displayString(){
        $result=$this->resultDecorator->resultSet;
        $str=”;
        while($row=mysql_fetch_assoc($result)){
            $str.=$row['id'].’ ‘.$row['name'].’ ‘.$row
['email'].'<br />';
        }
        return $str;
    }
}

Did you think that building another decorator class was really harder? Not at all! As you can see, the above class accepts an object of type “ResultDecorator” and returns a completely formatted result set, via its “displayString()” method. In this case, I used only a “<br />” tag for modeling the respective dataset, but this might be entirely modified to include more complex tag formatting.

As shown above, implementing the decorator pattern allowed me to add more functionality to the original “Result” class, without having to change its initial structure. Indeed, this is a very cool and handy concept.

Now, let me show you how to create a couple of additional decorator classes, which are capable of returning MySQL result sets, both as XML data and arrays respectively. The definitions of these classes are listed below, therefore please examine their source code:

// define ‘ArrayResultDecorator’ class
class XMLResultDecorator extends ResultDecorator{
    private $resultDecorator;
    // pass ‘ResultDecorator’ object to the constructor
    public function __construct(ResultDecorator $resultDecorator){
        $this->resultDecorator=$resultDecorator;
    }
    // display result set as formatted string
    public function displayXML(){
        $result=$this->resultDecorator->resultSet;
        $xml='<?xml version=”1.0″ encoding=”iso-8859-1″?>';
        $xml.='<users>’.”n”;
        while($row=mysql_fetch_assoc($result)){
            $xml.='<user><id>’.$row['id'].'</id><name>’.$row
['name'].'</name><email>’.$row['email'].'</email></user>’.”n”;
        }
        $xml.='</users>';
        return $xml;
    }
}
// define ‘ArrayResultDecorator’ class
class ArrayResultDecorator extends ResultDecorator{
    private $resultDecorator;
    private $resultArray=array();
    // pass ‘ResultDecorator’ object to the constructor
    public function __construct(ResultDecorator $resultDecorator){
        $this->resultDecorator=$resultDecorator;
    }
    // get result set as array
    public function getArray(){
        $result=$this->resultDecorator->resultSet;
        while($row=mysql_fetch_row($result)){
            $this->resultArray[]=$row;
        }
        return $this->resultArray;
    }
}

As you’ll surely realize with reference to the above classes, they’re very similar to the previous one. In this case, both of them also take an object of type “ResultDecorator” and return differently-formatted result sets by their “displayXML()” and “getArray()” method respectively.

What makes these classes really interesting is their capability to expand the functionality of the original “Result” class without having to modify its signature. This is what I would call a good example of the decorator pattern in action!

Well, now that you know how all the decorator classes look, it’s time to put them to work, so you can have a better idea of how they fit into the potential context of a Web application. For this reason, below I’ve set up an example which shows how to use each class separately. Please have a look:

try{
    // connect to MySQL
    $db=new MySQL(array
(‘host’=>’host’,’user’=>’user’,’password’=>’password’,
‘database’=>’mydatabase’));
    // get result set
    $result=$db->query(‘SELECT * FROM users’);
    // instantiate ‘ResultDecorator’ object
    $resultDecorator=new ResultDecorator($result);
    // instantiate ‘StringResultDecorator’ object
    $strResultDecorator=new StringResultDecorator
($resultDecorator);
    // display result set as formatted string
    echo $strResultDecorator->displayString();
}
catch(Exception $e){
    echo $e->getMessage();
    exit();
}

In the above example, first I established a connection to MySQL, then fetched a result set from a hypothetical “USERS” database table, and finally returned it as a formatted string, by using the “displayString()” method. Short and simple, right?

Now, suppose you want to return the same MySQL result set, but this time as XML data. The below script does precisely that:

try{
    // connect to MySQL
    $db=new MySQL(array
(‘host’=>’host’,’user’=>’user’,’password’=>’password’,
‘database’=>’mydatabase’));
    // get result set
    $result=$db->query(‘SELECT * FROM users’);
    // instantiate ‘ResultDecorator’ object
    $resultDecorator=new ResultDecorator($result);
    $xmlResultDecorator=new XMLResultDecorator($resultDecorator);
    header(‘Content-Type: text/xml’);
    // display result set as XML data
    echo $xmlResultDecorator->displayXML();
}
catch(Exception $e){
    echo $e->getMessage();
    exit();
}

And lastly, the example ends by showing how to return the result set in question as an array structure:

try{
    // connect to MySQL
    $db=new MySQL(array
(‘host’=>’host’,’user’=>’user’,’password’=>’password’,
‘database’=>’mydatabase’));
    // get result set
    $result=$db->query(‘SELECT * FROM users’);
    // instantiate ‘ResultDecorator’ object
    $resultDecorator=new ResultDecorator($result);
    $arrayResultDecorator=new ArrayResultDecorator
($resultDecorator);
    // get result set as array
    echo $arrayResultDecorator->getArray();
}
catch(Exception $e){
    echo $e->getMessage();
    exit();
}

All right, as you saw, returning MySQL result sets in different formats without changing the initial definition of the pertinent “Result” class is a no-brainer process, considering the correct implementation of the decorator pattern in PHP. Of course, I should mention that the same result might be obtained with inheritance, but as I stated before, there are times when you need to work with objects of different types.

Final thoughts

Sad but true, our journey surrounding the creation of decorator classes has ended. I hope that all the practical examples that you learned here will serve as a good introduction for understanding the development and application of decorator objects in PHP even better. See you in the next PHP tutorial!

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

chat sex hikayeleri Ensest hikaye