Home arrow PHP arrow Page 4 - Using Directory Iterators and MySQL with Adapter Objects with PHP

Adapting MySQL result sets - PHP

If you’re a PHP programmer who’s searching for a comprehensive tutorial on how to create adapter classes with PHP 5, them look no further. Welcome to the final installment of the series “Implementing adapter objects with PHP.” Made up of two parts, this series teaches you how to implement the adapter design pattern in PHP 5, and it accompanies the corresponding theory with educational examples.

  1. Using Directory Iterators and MySQL with Adapter Objects with PHP
  2. Working with directory iterators and adapters together
  3. Putting the adapter class to work
  4. Adapting MySQL result sets
By: Alejandro Gervasio
Rating: starstarstarstarstar / 6
December 13, 2006

print this article



As I expressed in the previous section, the last example that I plan to set up here concerning the implementation of the adapter pattern with PHP 5 consists basically of expanding the functionality of a MySQL result set handling class, obviously without having to appeal to the goodies of inheritance.

That being said, I listed the two base classes responsible for connecting to MySQL, running queries and so forth, as well as for handling data sets. Have a look at them, please:

// define 'MySQL' class class MySQL{     private $conId;     private $host;     private $user;     private $password;     private $database;     private $result;     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 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 database table rows     public function fetchRow(){         return mysql_fetch_assoc($this->result);     }     // count database table 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;     }     // obtain last insertion ID     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(!int($row)||$row<0){             throw newException('Invalid result set offset');         }   if(!mysql_data_seek($this->result,$row)){             throw new Exception('Error seeking data');         }     } }

After examining the above two classes, you'll probably find them familiar, since I used them in some of my previous PHP articles. However, this time I want you pay attention to the respective "Result" class, because I'll use it as the starting point for extending its functionality via an adapter class.

Now, say you want to provide this class with the ability to return completely-formatted result sets, but as I said before, without deriving a subclass from it. Of course, if you learned something from the examples that I showed previously, then you'll have the right answer for doing this: an adapter class!

Precisely, based on this premise, below I defined an adapter class that extends the capacity of the original "Result" and is able to display entirely formatted data sets. The signature for this class is the following:

// define 'ResultAdapter' class class ResultAdapter{     private $resultObj;     public function__construct(Result $resultObj){   $this->resultObj=$resultObj;     }     // get formatted result set     public function fetchFormattedResult($fieldDelimiter=' ',
$closeTag='</p>'){         $output='';         $opentag=str_replace('/','',$endTag);        while($row=$this->resultObj->fetchRow()){             $tempOutput='';             foreach($row as $data){                  $tempOutput.=$fieldDelimiter.$data;             }           $output.=$openTag.$tempOutput.$closeTag;         }       unset($openTag,$closeTag);         return $output;     } }

As you can see, the above defined adapter class certainly isn't rocket science at all. All I did here was pass in the original "Result" object to the corresponding constructor and create a specific "fetchFormattedResult()" method to provide data sets with a certain look and feel.

One possible implementation of the prior result set adapter class can be appreciated by examining the following script:


try{     // connect to MySQL     $db=new MySQL(array('host'=>'host','user'=>'user',
'password'=>'password','database'=>'database'));     // get result set object    $result=$db->query('SELECT * FROM users');     // instantiate 'ResultAdapter' object     $resultAdapter=new ResultAdapter($result);     // display formatted result set     echo $resultAdapter->fetchFormattedResult();     /*     displays the following data wrapped up into paragraphs:     1 user1 user1@domain.com     2 user2 user2@domain.com     3 user3 user3@domain.com     4 user4 user4@domain.com     5 user5 user5@domain.com     6 user6 user6@domain.com     7 user7 user7@domain.com     8 user8 user8@domain.com     9 user9 user9@domain.com     10 user10 user10@domain.com     */ } catch(Exception $e){     echo $e->getMessage();     exit(); }


Concerning the above example, all the rows contained in the sample "USERS" database table have been displayed inside paragraphs, via the corresponding "fetchFormattedResult()" method that belongs to the previous "ResultAdapter" class.

Here, it's clear to see how easy it is to create an adapter class without using inheritance. Of course, feel free to tweak the code of all the examples that I provided here, thus you can experiment with introducing your own modifications.

Final thoughts

Finally, we've come to the end of this series. In these two articles, I gave you some handy pointers on how to create adapter classes with PHP 5, in case you can't use inheritance as the approach for extending the functionality of a given class.

As I explained in these tutorials, the adapter pattern is more suitable to apply in situations where it's not only necessary to expand the capacity of a class, but the class must also fit the requirements of a third object.  As usual, see you in the next PHP series!

>>> More PHP Articles          >>> More By Alejandro Gervasio

blog comments powered by Disqus
escort Bursa Bursa escort Antalya eskort


- Hackers Compromise PHP Sites to Launch Attac...
- Red Hat, Zend Form OpenShift PaaS Alliance
- PHP IDE News
- BCD, Zend Extend PHP Partnership
- PHP FAQ Highlight
- PHP Creator Didn't Set Out to Create a Langu...
- PHP Trends Revealed in Zend Study
- PHP: Best Methods for Running Scheduled Jobs
- PHP Array Functions: array_change_key_case
- PHP array_combine Function
- PHP array_chunk Function
- PHP Closures as View Helpers: Lazy-Loading F...
- Using PHP Closures as View Helpers
- PHP File and Operating System Program Execut...
- PHP: Effects of Wrapping Code in Class Const...

Developer Shed Affiliates


Dev Shed Tutorial Topics: