Home arrow PHP arrow Page 4 - Caching Result Sets in PHP: Implementing the Caching System in PHP 5

Completing the caching application: assembling the relevant classes - PHP

Welcome to the final part of the series “Caching Result Sets in PHP.” Hopefully, the last chapter of this tutorial will help you to put together all of the classes developed in the previous part, and demonstrate how the complete caching system can be implemented in a PHP 5 controlled environment.

TABLE OF CONTENTS:
  1. Caching Result Sets in PHP: Implementing the Caching System in PHP 5
  2. Caching result sets in an PHP 5 scenario: a detailed look at the “Cache” class
  3. Traversing an array structure: developing an array Iterator
  4. Completing the caching application: assembling the relevant classes
  5. A practical approximation: putting the caching application to work
By: Alejandro Gervasio
Rating: starstarstarstarstar / 6
November 07, 2005

print this article
SEARCH DEV SHED

TOOLS YOU CAN USE

advertisement

At this point, we’re armed with the knowledge and the classes needed to implement successfully the complete caching system. To begin with, let’s first list the source code for each one of the reviewed classes and then set up an illustrative example. Here is the first required class,  “MySQL”, which, as you probably remember, looked like this:

// class MySQL

class MySQL{
            private $conId; // connection identifier
            private $host; // MySQL host
            private $user; // MySQL username
            private $password; // MySQL password
            private $database; // MySQL database
            // constructor
            public function __construct($options=array()){
                        // validate incoming parameters
                        if(count($options)>0){
                                   foreach($options as
$parameter=>$value){
                                               if(empty($value)){
                    throw new Exception('Invalid parameter
'.$parameter);
                }
                $this->{$parameter}=$value;
                                   }
                                   // connect to MySQL
                                   $this->connectDB();
                        }
                        else {
                                   throw new Exception('No
connection parameters were provided');
                        }
            }
            // connect to MYSQL server and select 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');
                        }
            }
            // perform query
            public function query($query){
                        if(!$this->result=mysql_query
($query,$this->conId)){
                                   throw new Exception('Error
performing query '.$query);
                        }
                        // return new Result object
                        return new Result($this,$this->result);
            }
}

Then, the next piece of the puzzle, the “Result” class:

//class Result

class Result {
            private $mysql; // instance of MySQL object
            private $result; // result set
            public function __construct(&$mysql,$result){
                        $this->mysql=&$mysql;
                        $this->result=$result;
            }
            // fetch row
            public function fetchRow(){
                        return mysql_fetch_array($this-
>result,MYSQL_ASSOC);
            }
            // 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 from 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(!mysql_data_seek($this->result,$row)){
                                   throw new Exception('Error
seeking data');
                        }
            }
}

Next, let’s list the code for the “arrayProcessor” class:

// class arrayProcessor

class arrayProcessor{
private $data; // data array for processing
            // constructor
            public function __construct($data=array()){
                        if(!is_array($data)){
                                               throw new
Exception('Invalid data array');
                        }
                        $this->data=$data;
            }
             // get first array element
            public function getFirstElement(){
                        if(!$data=reset($this->data)){
                                               throw new
Exception('Error fetching first array element');
                        }
                        return $data;
            }
            // get current array element
            public function getCurrentElement(){
                        if(!$data=current($this->data)){
                                               return false;
                        }
                        return $data;
            }
            // get last array element
            public function getLastElement(){
                        if(!$data=end($this->data)){
                                               throw new
Exception('Error fetching last array element');
                        }
                        return $data;
            }
            // get previous array element
            public function getPreviousElement(){
                        if(!$data=prev($this->data)){
                                               return false;
                        }
                        return $data;
            }
            // get next array element
            public function getNextElement(){
                        if(!$data=next($this->data)){
                                               return false;
                        }
                        return $data;
            }
            // reverse array elements
            function reverseElements($prekeys=true){
                        if(!$data=array_reverse($this-
>data,$prekeys)){
                                               throw new
Exception('Error reversing array elements');
                        }
                        return $data;
            }
            // sort array elements
            public function sortElements(){
                        if(!sort($this->data)){
                                               throw new
Exception('Error sorting array elements');
                        }
                        return $this->data;
            }
            // get range of array elements
            public function getRange($offset,$length){
                        if(!$data=array_slice($this->data,intval
($offset),intval($length))){
                                               throw new
Exception('Error fetching range of elements');
                        }
                        return $data;
            }
            // get random array element
            public function getRandomElement(){
                        if(!shuffle($this->data)){
                                               throw new
Exception('Error shuffling array elements');
                        }
                        return $this->data[0];
            }
            // search element in array
            public function searchElement($keyword){
                        return array_search($keyword,$this-
>data);
            }
            // count array elements
            public function countElements(){
                        if(!$data=count($this->data)){
                                               throw new
Exception('Error counting array elements');
                        }
                        return $data;
            }
}

Finally, the core piece of the caching system, the “Cache” class:

class Cache{
            private $mysql;  // instance of MySQL object
            private $result; // instance of Result object
            private $arrproc; // instance of arrayProcessor object
            private $expiry; // cache expire time in seconds
            private $cacheFile; // cache file
            private $data; // result data array
            // constructor
            public function __construct(&$mysql,$expiry=7200,$cacheFile='default_cache.txt'){
                        $this->mysql=&$mysql;
                        $this->expiry=$expiry;
                        $this->cacheFile=$cacheFile;
                        $this->data=array();
            }
            // if cache is valid, perform query against database. Otherwise, get results from cache file
            public function query($query){
                        if(!$this->isValid()){
                                   $this->result=&$this->mysql-
>query($query);
                                   // read data from MySQL
                                   $this->data=$this->write();
                        }
                        else {
                                   // read data from cache file
                                   $this->data=$this->read();
                        }
                        // create a new instance of
arrayProcessor object
                        $this->arrproc=new arrayProcessor($this-
>data);
            }
            // write cache file
            private function write(){
                        if(!$fp=fopen($this->cacheFile,'w')){
                                   throw new Exception('Error
opening cache file');
                        }
                        // lock cache file
                        if(!flock($fp,LOCK_EX)){
                                   throw new Exception('Unable to
lock cache file');
                        }
                        // get result array from query result
                        while($row=$this->result->fetchRow()){
                                   $contents[]=$row;
                        }
                        // write serialized data to cache file
                        if(!fwrite($fp,serialize($contents))){
                                   throw new Exception('Error
writing to cache file');
                        }
                        // unlock cache file
                        flock($fp,LOCK_UN);
                        fclose($fp);
                        unset($fp,$row);
                        // return query result
                        return $contents;
            }
            // read cache file
            private function read(){
                        if(!$contents=unserialize
(file_get_contents($this->cacheFile))){
                                               throw new
Exception('Error reading cache file');
                        }
                        // return cached data
                        return $contents;
            }
            // determine if cached data is valid or not (time
expiry triggered cache)
            private function isValid(){
                        if(file_exists($this->cacheFile)
&&filemtime($this->cacheFile)>(time()-$this->expiry)){
                                   return true;
                        }
                        return false;
            }
            // fetch row
            public function fetchRow(){
                        if(!$row=$this->arrproc-
>getCurrentElement()){
                                   return false;
                        }
                        $this->arrproc->getNextElement();
                        return $row;
            }
            // fetch all rows
            public function fetchAll(){
                        $this->arrproc->countElements();
                        return $this->data;
            }
            // count rows
            public function countRows(){
                        return $this->arrproc->countElements();
            }
            // fetch range of rows
            public function fetchRange($offset,$length){
                        return $this->arrproc->getRange
($offset,$length);
            }
}

Okay, I think that nothing was left out here. Now, we’re ready to set up an example. Thus, join me in the next section, to see how easily the caching system is put to work.



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

blog comments powered by Disqus
escort Bursa Bursa escort Antalya eskort
   

PHP ARTICLES

- 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: