awc_cache Tutorial
awc_cache allows the creation of a file cache. You can add data files to the cache, and read or delete them from the cache. Any necessary directories are created automatically.
Installation
-
Copy the file inc/awc_cache.class.php to a directory in your include_path.
- You might want to edit the default property values. These are used when the constructor is called with no property value definitions in the function arguments. These default values are constants defined near the top of awc_cache.class.php, in between the comment lines "// START Constants for default property values" and "// END Constants for default property values".
- If you are going to use the included bash script for purging the cache of files not accessed for a certain period of time, copy the file bin/trim_cache.sh to somewhere in your executable path.edit the $DAYS and $CACHEDIR definitions near the top of the script.
- $data is the data to store.
- $file is the name of the file the data will be stored in. This is relative to the $root property.
If it includes '/' characters, any required subdirectories will also be created.
Creating A Cache
Include the class file:
include_once 'awc_cache.class.php';
Instantiate an awc_cache object, with properties set to their default values (described above):
$oCache = new awc_cache;
Or, instantiate an object, and set the property values at the same time. The constructor takes an array of property values to set:
$aParams = array( 'root' => '/full/path/to/cache/root/dir'
, 'expiry' => 60
, 'file_perms' => 0755 );
$oCache = new awc_cache( $aParams );
If only a single scalar value is given as an argument to the constructor, that value is assumed to be the root directory:
$oCache = new awc_cache( '/full/path/to/cache/root/dir' );
You can get/set the properties at any time using the get_ and set_ methods:
$oCache->set_root( '/new/path/to/cache/root/dir' );
$root = $oCache->get_root();
$oCache->set_expiry( 60 );
$oCache->set_file_perms( 0755 );
Adding Content To The Cache
The add() method takes two arguments, $data and $file.
In this example, directory 'dir1' will be created under the cache root directory. The directory 'dir2' will be created under 'dir1', and the file 'file1' will be created under that. 'file1' will contain the contents of $data:
$cache_fname = "dir1/dir2/file1";
$data = get_html();
$oCache->add( $data, $cache_fname );
Retrieving Content From The Cache
Call the get() method with a filename as the only argument. The contents of the file will be returned, or false
will be returned on error (for example if the file doesn't exist).
To retrieve the contents of the file created earlier:
$cache_fname = "dir1/dir2/file1";
$data = $oCache->get($cache_fname);
if ( $data !== false )
echo "Success: \$data: ".print_r($data,1)."<br>";
else
trigger_error( "Error: couldn't read cache" );
Checking If Cached Files Have Expired
The cache object has an $expiry property. This is the age a cached file must be, in seconds, to be considered 'expired' or 'no longer cached'. If you want data to be re-generated every so often (for example, a web site's news page), you would set expiry to a non-zero integer, and call the is_cached() method prior to generating content to decide whether to actually re-generate the content, or just use the cached version of the content.
The is_cached() method returns boolean true if the file is cached (ie is stored in the file cache and is not older then $expiry seconds), false otherwise. The integer 0 is returned in the case of an error:
$cache_fname = "dir1/dir2/file1";
$bIsCached = $oCache->is_cached( $cache_fname );
if ( $bIsCached === 0 )
die( "Error while checking if file '$file' is cached" );
if ( $bIsCached === true )
echo "File '$file' is cached";
else ( $bIsCached === false )
echo "File '$file' either doesn't exist in the cache or has expired";
Removing files from the cache
Use the clear() method to delete files from the cache. Give a filename or directory as the method's argument. If a directory name is given, all files and subdirectories will be deleted.
If no argument or the empty string '' is given, the entire cache is deleted. If the string '/' is given, the root directory is also deleted.
// Delete a file
$fname_to_delete = "dir1/dir2/file1";
$oCache->clear( $fname_to_delete );
// Delete a directory and all its files and subdirectories
$dir_to_delete = "dir1";
$oCache->clear( $dir_to_delete );
// Delete the entire cache
$oCache->clear(); // or $oCache->clear('');
// Delete the entire cache, including the root directory
$oCache->clear('/');
Trimming The Cache
You can use the bash script trim_cache.sh to remove from the cache all files not accessed within a certain number of days. This is useful if you need to conserve disk space.
BilliardSearch.net, for example, is a search engine that stores the results of user queries in a file cache. Many of the search phrases people use are not going to be used again for a long time, if ever. The cache would quickly eat up all available disk space if we left all this seldom-used data lying around. So we run trim_cache.sh once a day as a cron job to remove from the cache any files that have not been read in the last N days to keep the cache to a reasonable size.
Edit the values of the $DAYS and $CACHEDIR variables before you run the script. These are located near the top of the file between:
# # START User editable #
and:
# # END User editable #
Example
For this example, we'll take a typical situation where it might be desirable to cache web page content - a website's news story page. Every time someone views a news story, the script behind the web page must fetch the data from the database and then process that data via PHP to produce HTML which is then served to the user's browser.
This processing uses up precious system resources like CPU processing time and database connections. To keep your site lean and mean by using system resources only when needed, you should generate the HTML for the news story only on the first request, and then cache it. On subsequent requests, you just pull the cached version from the filesystem without using up system resources to generate the page again and again.
// Get the ID of the news story we're to display
$id = isset($_GET['id']) ? (int)$_GET['id'] : 0;
if ( $id <= 0 )
die( "invalid $id" );
// Create cache object
$aParams = array( 'root' => $base_dir.'/cache'
, 'expiry' => 60 * 5 );
$oCache = new awc_cache( $aParams );
// Create a cache filename, which must be unique to this story
$cache_fname = "news/story/{$id}.html";
// Check whether this story is still in the cache (and hasn't expired), or
// whether we should regenerate it
$bIsCached = $oCache->is_cached( $cache_fname );
if ( $bIsCached )
{
// File has not expired - use the cached content
$html = $oCache->get( $cache_fname );
}
else
{
// File has expired (or hasn't been created yet) - we need to
// generate the content
$html = generate_news_story_html( $id );
// Now cache the content
$oCache->add( $html, $cache_fname );
}
echo $html;
Of course, there is a chance a news story might change after you've cached it, so you should either:
- choose a sensible
expiry time, so changes will go live in a reasonable time;
- or better, use an expiry time of boolean false on your cache (so it will never expire), and use awc_cache in your
admin system to clear()
the cached copy every time the story is edited.