HomePHP Page 4 - Caching Result Sets in PHP: A Content-Change Triggered Caching System
Wrapping the code: defining the “readData()” and “readQueryResult()” functions - PHP
Caching within the context of PHP application acceleration can be triggered based on three possible categories: time expiry, content change, and manually. This article covers an application that triggers the caching mechanism based on a content change condition.
Probably wrapping the above code into a couple of containing functions won’t have a big impact on its functionality, but it helps to keep the code more compact and readable. Again, this is a matter of personal preference. Whatever the case, we might define a “readData()”, function which contains most of the logic implemented in the caching script, as well as a “readQueryResult()” function, useful for connecting to MySQL, running a query and returning a result set in the form of an array. Doing so, the “readQueryResult()” function would look like this:
function readQueryResult($options=array()){ // check parameters if(count($options)<5){ trigger_error('Invalid number of parameters'); exit(); } // create connection variables foreach($options as $key=>$value){ ${$key}=$value; } // connect to MySQL if(!mysql_connect($host,$user,$password)){ trigger_error('Error connecting to the server '.mysql_error()); exit(); } // select database if(!mysql_select_db($database)){ trigger_error('Error selecting database '.mysql_error()); exit(); } // check if query starts with SELECT if(!preg_match("/^SELECT/",$query)){ trigger_error('Invalid query. Must start with SELECT'); exit(); } if(!$result=mysql_query($query)){ trigger_error('Error performing query '.$query.mysql_error()); exit(); } while($row=mysql_fetch_array($result,MYSQL_ASSOC)){ $data[]=$row; } return $data; }
And the “readData()” function would be defined as follows:
function readData($options=array(),$cacheFile='default_cache.txt'){ // check to see if cache file is valid (content changed triggered caching) if(file_exists($cacheFile)){ if(rand(1,100)>90){ // read randomly data from MySQL $data=readQueryResult($options); // read cache data $cacheData=readCache($cacheFile); // compare cached data with fresh data // if content has changed then force new cache generation (md5(serialize($cacheData))==md5(serialize($data)))? $data=$cacheData:writeCache($data,$cacheFile); } else{ // read data from cache file $data=readCache($cacheFile); } } else{ // read data from MySQL $data=readQueryResult($options); // store data in cache file writeCache($data,$cacheFile); } return $data; }
The first function simply connects to MySQL, selects the database and runs a SELECT query, returning the result set as an array. The second function implements the core logic of the script, as you can clearly appreciate.
Having defined the wrapping functions, the script can be run as easily as 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,'cache_file.txt'); // display data foreach($data as $key=>$row){ echo 'First Name :'.$row['firstname'].' Last Name :'.$row ['lastname'].'<br />'; }
When the script is first run, the data will be returned as a result set after performing the SQL query, and then stored in the cache file. The subsequent requests to the script will return data either from the database or the cache file, depending on the randomly generated number.
As you can see, the caching trigger might be easily changed to obey different rules. One possible addition would be writing a function that runs the query after a specified number of script executions, or by defining a function that manually deletes the cache file, thereby forcing a new cache generation. Possibilities are certainly numerous.
For those developers that want to play around with the above listed code, just jump straight to the next section, where its complete list is shown.