Home arrow PHP arrow Page 5 - Caching Result Sets in PHP: Porting the Code to PHP 5

The caching system’s core class: updating the “Cache” class - PHP

In this part of the series, you will see in detail an updated version of each class that composes the caching system, for a correct implementation in PHP 5. Also, the “Cache” class will be modified to work with an array processor class that handles array operations. It should help refresh your memory of techniques related to object-oriented programming.

TABLE OF CONTENTS:
  1. Caching Result Sets in PHP: Porting the Code to PHP 5
  2. One step prior to migrating: caching result sets with PHP 4
  3. Taking advantage of an improved object model: updating the caching system to PHP 5
  4. Yet another modified class: updating the “Result” class
  5. The caching system’s core class: updating the “Cache” class
By: Alejandro Gervasio
Rating: starstarstarstarstar / 6
October 31, 2005

print this article
SEARCH DEV SHED

TOOLS YOU CAN USE

advertisement

Since the “Cache” class implements the necessary logic to manipulate data either from a query result or from the cache file, I’ll explain in detail the changes applied to its structure.

As you hopefully remember, the class utilizes an array structure for handling result sets, which are serialized for caching purposes and unserialized for post processing. Considering that the majority of the class operations are carried out on simple arrays, it’d be highly desirable to develop an array iterator class that handles the most common tasks associated with arrays, and then create an instance of it (again, composition plays an important role) within the “Cache” class.

Bearing this concept in mind, let’s have a look at the updated definition for the “Cache” class. It is as follows:

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);
            }
}          

As you can see, now the class includes three objects for doing its work: a reference of a MySQL object, $this->mysql (this object is aggregated), an instance of a “Result” object, that is $this->result, and finally an instance of the array processor $this->arrproc, for performing array operations.

If this sounds rather confusing, let’s explain the logic of some methods. For instance, the “fetchRow()” method now uses the “getCurrentElement()” method that belongs to the array processor for fetching the current element within the result set array. Similarly, this technique is used to count rows, through the “countRows()” method, or even fetch a limited result set using “fetchRange()”. See how we’re using the functionality provided by the array processor? Now, the inclusion of this object should be clear for the correct implementation for the “Cache” class.

By assigning clearly delineated responsibilities to different classes, we’re writing better and more portable code that can be reused in any number of projects.

Of course, there are many things to be reviewed yet, in order to get the big picture about the caching system. Certainly, we need to see in detail the code for the array processor class, as well as how the classes fit into the application. All right, don’t get anxious, because these topics will be fully explained in the next part of the series.

To wrap up

Through the course of this part, we’ve seen in detail the updated version of each class that composes the caching system, for a correct implementation in PHP 5. Also, the “Cache” class has been modified to work with an array processor class that handles array operations. Hopefully, the article has been didactic and useful for refreshing techniques related to object-oriented programming.

With all of the code exposed here, I guess you’ll spend a while adapting it to suit your needs. However, don’t miss the next part, where the complete caching system is put to work. Until then, stay in touch!



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