PHP Caching object for XCache or eAccelerator


Since caching should be an integral part of any (homebrew) CMS a simple static caching object is discussed for both the XCache and eAccelerator modules in PHP.

Caching should be embedded in every web application that has a database backend, it is very inefficient to run the same query over and over again for each pageview.

For example querying the database with
SELECT `article_title`, `article_text` FROM `articles` WHERE `article_id` = 5
usually returns the same result over and over again. An editor could do an update of the article so we would like a cache which is refreshed every n seconds, this is the most elementary approach; a real cache should only update when the data has been altered.

Which properties are needed for a fully functional caching module?

  • Store data in the cache at position x, optionally add an extra parameter e to indicate the lifetime of the data: update the data in the cache.
  • Get the value of the cache for cache key x.
  • Has any data been added to the cache for cache key x?
  • Remove the data from the cache for cache key x.

We can use the cache to store simple data: string, int or float or to store objects and arrays. Depending on the caching module in use we must pack the data: serialize it to be a simple text string. When loading data from the cache we have to unpack the data. Two extra functions have been added to the caching object:

These function are only used when needed.

In order to be able to switch between XCache or eAccelerator (not both!) several elaborate schemes could be implemented. However since we use a cache for a speedup and we do not switch runtime from one cache module to another we choose to comment or uncomment the specific function calls.

Note that if the caching module for PHP fails to load or is not available on the current server the module switches to a very simple caching system: using a global variable for caching. This is just a fallback mechanism and should not be used in a production environment.

The Set function takes an optional third parameter $ttl which is given in seconds, this parameter defaults to zero thus setting the cache for the given key to "never expire".

Note: the cache is a static object.

The complete object is shown next:

$global = array();
 
define( 'CACHE', is_callable( 'eaccelerator_get' ) );
//define( 'CACHE', is_callable( 'xcache_get' ) );
 
class Cache
{
    static function CUnset( $name )
    {
    	if ( CACHE )
	    	//return xcache_unset( $name );
	    	return eaccelerator_rm( $name );
 
	    global $global;	
	    unset( $global['cache'][$name] );
    	return true;
    }
 
    static function CIsSet( $name )
    {
    	if ( CACHE )
    		//return xcache_isset( $name );
    		return !is_null( eaccelerator_get( $name ) );
 
	    global $global;	
    	return isset( $global['cache'][$name] );
    }
 
    static function Set( $name, $value, $ttl = 0 )
    {
    	if ( CACHE )
	    	//return xcache_set( $name, $value, $ttl );
	    	return eaccelerator_put( $name, Cache::Serialize( $value ), $ttl );
 
	    global $global;	
    	$global['cache'][$name] = $value;
    }    
 
    static function Get( $name )
    {
    	if ( CACHE )
	    	//return xcache_get( $name );
	    	return Cache::Unserialize( eaccelerator_get( $name ) );
 
	    global $global;	
	    return $global['cache'][$name];
    }
 
    static function Serialize( $value )
    {
    	return serialize( $value );
    }
 
    static function Unserialize( $value )
    {
    	return unserialize( $value );
    }
}

Back to top