Home arrow PHP arrow Page 4 - Caching Result Sets in PHP: Cost-efficient PHP acceleration

Putting the pieces together: implementing the result set caching script - PHP

With many websites using a database backend for storing and delivering content, certain common problems arise. One of these is a situation that causes the server to slow down or even bring the system to a complete halt. What can you do to reduce the load on your server? This tutorial discusses one method, a result set caching system, and demonstrates how to implement it with either a procedural or an object-oriented approach.

TABLE OF CONTENTS:
  1. Caching Result Sets in PHP: Cost-efficient PHP acceleration
  2. The first caching approximation: serializing and unserializing data
  3. A fully functional result set caching system: modifying the original script
  4. Putting the pieces together: implementing the result set caching script
By: Alejandro Gervasio
Rating: starstarstarstarstar / 23
October 03, 2005

print this article
SEARCH DEV SHED

TOOLS YOU CAN USE

advertisement

Undoubtedly, there is much to be gained by implementing a caching system like this. If a website delivers content that doesn't change very frequently, let's say by offering a list of articles or products, we might be able to cache the data in a file and force a new cache generation based on a time expiry caching strategy.

In this case, the script follows that approach, establishing a time expire value in seconds for the validity of the cache file. The first occurrence of the script connects to MySQL and obtains the corresponding result set, which after being serialized, is cached to the file. As a result, all of the subsequent page requests will display the data retrieved from the cache, until the time expiry will be reached.

The above logic is better understood by looking at the code listed below:

// define cache file
$cacheFile='cacheFile.txt';
// define expire time in seconds (2 hours)
$expireTime=7200;
// check to see if cache file is valid (time triggered caching)
if(file_exists($cacheFile)&&filemtime($cacheFile)>(time()-
$expireTime)){
    // read data from cache file
    $data=readCache($cacheFile);
}
else{
    // read data from MySQL
    connectMySQL('host','user','password','databasename');
    $result=query('SELECT * FROM users');
    // store result set in array
    while($row=mysql_fetch_array($result,MYSQL_ASSOC)){
        $data[]=$row;
    }
    // store serialized data in cache file
    writeCache($data,$cacheFile);
}
// display data
foreach($data as $key=>$row){
    echo 'First Name :'.$row['firstname'].' Last Name :'.$row['lastname'].'<br />';
}

As you can see, the above script first defines to the cache file where to store the result set, in this case "cacheFile.txt". Then, it specifies the time period, expressed in seconds, for considering the cached data valid. For this particular example, I've specified a cache validity of two hours (7,200 seconds). These values are defined in the following lines:

// define cache file
$cacheFile='cacheFile.txt';
// define expire time in seconds (2 hours)
$expireTime=7200;

As long as the time expiry is not reached, the result set is obtained from the cache. Otherwise, a new connection to MySQL is established, performing a query and returning a new result set, which results in another cache generation. This process is carried out by the lines:

// check to see if cache file is valid (time triggered caching)
if(file_exists($cacheFile)&&filemtime($cacheFile)>(time()-
$expireTime)){
    // read data from cache file
    $data=readCache($cacheFile);
}
else{
    // read data from MySQL
    connectMySQL('host','user','password','databasename');
    $result=query('SELECT * FROM users');
    // store result set in array
    while($row=mysql_fetch_array($result,MYSQL_ASSOC)){
        $data[]=$row;
    }
    // store serialized data in cache file
    writeCache($data,$cacheFile);
}

Finally, the script is capable of directly caching results sets without major inconveniencies. Eventually, we might introduce another improvement by wrapping the above code into a function. Doing so, the overall code would hide all of the internal processing, being even more flexible and portable.

Thus, this new wrapping function, which I've denominated "readData()" (or anything you like), is defined as follows:

function readData($options=array),$expireTime=7200,$cacheFile='default_cache.txt')
{
    // check parameters
    if(count($options)<5){
        trigger_error('Invalid number of parameters');
        exit();
    }
    // create connection variables
    foreach($options as $key=>$value){
        ${$key}=$value;
    }
    // check if query starts with SELECT
    if(!preg_match("/^SELECT/",$query)){
        trigger_error('Invalid query. Must start with SELECT');
        exit();
    }
    // check to see if cache file is valid (time triggered
caching)
    if(file_exists($cacheFile)&&filemtime($cacheFile)>(time()-
$expireTime)){
        // read data from cache file
        $data=readCache($cacheFile);
    }
    else{
        // read data from MySQL
        connectMySQL($host,$user,$password,$database);
        $result=query($query);
        // store result set in array
        while($row=mysql_fetch_array($result,MYSQL_ASSOC)){
            $data[]=$row;
        }
        // store serialized data in cache file
       writeCache($data,$cacheFile);
    }
    return $data;
}

Now, suppose that we want to cache a result set for 24 hours, and store it in the "cache_file.txt" cache file. We may invoke the function with these parameters and then display the data, like this:

// read data from MySQL or cache file
$options=array
('host'=>'host','user'=>'user','password'=>
'password','database'=>'
databasename','query'=>'SELECT * FROM users');
$data=readData($options,86400,'cache_file.txt');
// display data
foreach($data as $key=>$row){
    echo 'First Name :'.$row['firstname'].' Last Name :'.$row
['lastname'].'<br />';
}

Definitiely the code is much more compact and readable. However, as you can see, it maintains the benefits inherent to caching result sets. Notice that the function returns the data either from MySQL or the cache file. In this circumstance, I've chosen to display the result, but it might have been post-processed in some other way before sending it to the browser. As mentioned before, this caching method is more flexible than caching the entire HTML output.

To wrap up

In this first part of the series, I've demonstrated that building a result set caching system is a rather easy process. For developers working with a procedural approach, this solution can be used as a base structure for further improvements. However, there is still a long road in front of us.

In the second article, I'll implement a result set caching script based on a content-change caching trigger, exploring yet another nice possibility offered by this technique. So, get ready for next part!



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