Home arrow PHP arrow Page 2 - Caching Result Sets in PHP: Object Interaction Within a Caching System

The first link in the caching process: looking at the “Cache” class - PHP

In this article, we work directly with a standalone caching class, showing how it interacts with other objects. We will work with aggregation and composition to achieve our goals, which include implementing a time expiry based caching mechanism.

TABLE OF CONTENTS:
  1. Caching Result Sets in PHP: Object Interaction Within a Caching System
  2. The first link in the caching process: looking at the “Cache” class
  3. The second link in the caching process: overview of the “MySQL” class
  4. The third link in the caching process: a quick look at the “Result” class
  5. Chaining the links: putting the classes together
By: Alejandro Gervasio
Rating: starstarstarstarstar / 6
October 17, 2005

print this article
SEARCH DEV SHED

TOOLS YOU CAN USE

advertisement

In order to get a better understanding of the interaction process between classes, let’s remind ourselves of how the “Cache” class looks, since it’s the first relevant structure within the caching system. To refresh our memories, here is the complete definition for this class:

class Cache{
            var $mysql;  // instance of MySQL object
            var $result; // instance of Result object
            var $expiry; // cache expire time in seconds
            var $cacheFile; // cache file
            var $data; // result set array
            // constructor
            function Cache(&$mysql,$expiry=86400,$cacheFile='default_cache.txt'){
                        $this->mysql=&$mysql;
                        (is_int($expiry)&&$expiry>0)?$this-
>expiry=$expiry:$this->mysql->isError('Expire time must be a
positive integer');
                        $this->cacheFile=$cacheFile;
                        $this->data=array();
            }
            // if cache is valid, perform query and return a
result set. Otherwise, get results from cache file
            function query($query){
                        // check if query starts with SELECT
                        if(!preg_match("/^SELECT/",$query)){
                                   $this->mysql->isError('Invalid
query. Must start with SELECT');
                        }
                        if(!$this->isValid()){
                                   $this->result=$this->mysql-
>query($query);
                                   $this->data=$this->write();
                        }
                        else {
                                   $this->data=$this->read();
                        }
            }
            // write cache file
            function write(){
                        if(!$fp=fopen($this->cacheFile,'w')){
                                   $this->mysql->isError('Error
opening cache file');
                        }
                        if(!flock($fp,LOCK_EX)){
                                   $this->mysql->isError('Unable
to lock cache file');
                        }
                        while($row=$this->result->fetchRow()){
                                   $content[]=$row;
                        }
                        if(!fwrite($fp,serialize($content))){
                                   $this->mysql->isError('Error
writing to cache file');
                        }
                        flock($fp,LOCK_UN);
                        fclose($fp);
                        unset($fp,$row);
                        return $content;
            }
            // read cache file
            function read(){
                        if(!$content=unserialize
(file_get_contents($this->cacheFile))){
                                   $this->mysql->isError('Error
reading from cache file');
                        }
                        return $content;
            }
            // determine cache validity based on a time expiry
trigger
            function isValid(){
                        if(file_exists($this->cacheFile)
&&filemtime($this->cacheFile)>(time()-$this->expiry)){
                                   return true;
                        }
                        return false;
            }
            // fetch cache row
            function fetchRow(){
                        if(!$row=current($this->data)){
                                   return false;
                        }
                        next($this->data);
                        return $row;
            }
            // fetch all cache rows
            function fetchAll(){
                        if(count($this->data)<1){
                                   $this->mysql->isError('Error
accessing cache data');
                        }
                        return $this->data;
            }
            // count cache rows
            function countRows(){
                        if(!$rows=count($this->data)){
                                   $this->mysql->isError('Error
counting cache rows');
                        }
                        return $rows;
            }
}

So far, so good. Since the class has been explained in detail over the third part of the series, I won’t stop long on it. Let’s take a brief look at some of its most important features, before jumping directly into the source code for the other classes.

As we’ve seen before, the “Cache” class allows you to store an entire result set in a cache file for a given time period. Once the expiry has been reached, a new query is run for getting “fresh” data, and then the cache generation is carried out again. As long as the cached data is valid, it will be read from the file, being available for some kind of further processing.

Asides from the regular methods to handle programmatically the cached data, the class exposes some additional methods for fetching either single rows or multiple rows, as well as the ability to count rows.

Indeed, these features don’t present any difficulties. However, there are some interesting things within the class definition. Note that database connectivity tasks, query execution, and error handling are delegated to different classes. This implicitly means that there must be other objects that are passed to the “Cache” class for carrying out these specific operations.

Essentially, we can see that all of the database work is done by a MySQL object, which is passed to the class by its constructor. Therefore, it’s time to take a look at the MySQL abstraction class, responsible for connecting to MySQL, selecting databases and running queries.



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