Caching Result Sets in PHP: Object Interaction Within a Caching System - The first link in the caching process: looking at the “Cache” class
(Page 2 of 5 )
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.
Next: The second link in the caching process: overview of the “MySQL” class >>
More PHP Articles
More By Alejandro Gervasio