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

Caching result sets in an PHP 5 scenario: a detailed look at the “Cache” class - 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

To complete the process of developing the caching system, we have to analyze in detail the core “Cache” class and understand properly its logic. Although this class was already reviewed in the previous part of the series, it’s useful to refresh our memory and take a look at its definition. That way, it will be easier to explain how the array processor class fits into the programming schema.

The list for the “Cache” class is the following:

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’ve seen before, the class essentially handles the logic for reading a result set either from MySQL or from the specified cache file, based on a time expiry caching policy. Due to the fact that the class hides the internal processing behind the “query()” method, it’s possible to do a little refactoring and implement a different cache trigger or even a combination of triggers.

Asides from handling the caching trigger, the class exposes several additional methods for single and multiple row fetching, as well as for counting rows and returning a range of them. It’s easy to see that each of the methods that performs array operations, uses the methods provided by the array processor object.

This is best understood by taking a look at the following line, within the “query()” method:

// create a new instance of arrayProcessor object
$this->arrproc=new arrayProcessor($this->data);

Whenever this method is invoked, it instantiates an object from the “arrayProcessor” class, which is directly fed with the array obtained from the cache file, in case you have a valid caching period, or from the query resource.

Notice that the array processor object’s methods are used to fetch or count rows. However, it’s fairly easy to add more methods for more complex result set manipulation. For instance, suppose that we need to return a randomly selected row from a result set. This would be quickly done by using a method of the array processor that picks up a random element. Indeed, expanding the “Cache” class’ functionality would be a pretty straightforward process.

Since the “Cache” class relies heavily on the array processor object, it’s necessary to look at its structure. Doing so, the concepts explained above will be better grasped.



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