TracNav menu
Template Caches
The template cache has been developed to speed up patTemplate based applications. It will save you the overhead of analysing the template files, for every request. Instead, it will serailize the result of the reader and store it anywhere you like; on the next request to the same template, it will check, whether the file is still valid and load it from cache.
How does it work?
When you are calling patTemplate::readTemplatesFromInput(), patTemplate will include and instantiate the desired reader which will then load and analyze the template you specified. This will be done everytime the template is requested although the process is not influenced by any variables or user feedback. This technique has two drawbacks:
- The reader class consist of 1400+ lines of code, which have to be compiled
- The reader makes use of preg_* functions, which can get time consuming
To get rid of these performance brakes, I implemented the template cache, which implements a quite simple functionality: After the reader analyzed the template and returns an array containing the structure, the template cache will serialize this structure and store it with a unique key. On the next request, patTemplate asks the template cache, whether there's a stored structure for a specific key. If yes, it will be usnerialized and used instead of reading the template again.
Using a template cache
Like all patTemplate modules, using a template cache is easy. Basically, you just need to add one line of code to your scripts.
<?PHP
require_once 'pat/patErrorManager.php';
require_once 'pat/patTemplate.php';
$tmpl = &new patTemplate();
$tmpl->setRoot( 'templates' );
/**
* Use a template cache based on file system
*/
$tmpl->useTemplateCache( 'File', array(
'cacheFolder' => './tmplCache',
'lifetime' => 60 )
);
$tmpl->readTemplatesFromInput( 'page.tmpl', 'File' );
$tmpl->displayParsedTemplate();
?>
The first parameter in the call to useTemplateCache() defines which cache should be used. if you are unsured, which caches you have installed, take a look at the folder patTemplate/TemplateCache. The second parameter is an array with all parameters for the template cache. You'll have to check the documentation of the template cache you are using for a list of all supported parameters.
In the example that uses the 'File' cache, there are two parameters:
- cacheFolder defines, where the cache files will be stored
- lifetime defines, how long the cache is valid. In this case, we use a cache for 60 seconds. You may also set the cache to 'auto', if you want the cache to be rebuilt, when the source file changes.
Creating a new template cache
patTemplate ships with a template cache, that stores data on the filesystem. If you need a faster storage container, like shared memory, you may easily implement it. Create a new file in patTemplate/TemplateCache and create a class, that extends patTemplate_Cache. In this class, you only need to implement the following methods:
- array patTemplate_TemplateCache::load( string key, int modificationTime )
- boolean patTemplate_TemplateCache::write( string key, array templates )
The load() method will receive a unique key as well as the time, when the original file has been modified, if the reader supports this feature. You will have to check, whether there is a cache file for the specified key and whether it still is valid. If the file is valid, you will have to unserialize the stored data and return the resulting template structure to patTemplate. The write() method will receive the unique key, as well as the template structure, that has to be stored. Just serialize it and store it with the key, so it can be loaded at a later point.
Take a look at the code
To fully grasp, how the template cache works, take a look at the 'File' cache:
<?PHP
/**
* patTemplate Template cache that stores data on filesystem
*
* Possible parameters for the cache are:
* - cacheFolder : set the folder from which to load the cache
* - lifetime : seconds for which the cache is valid, if set to auto, it will check
* whether the cache is older than the original file (if the reader supports this)
*
* @package patTemplate
* @subpackage Caches
* @author Stephan Schmidt <schst@php.net>
*/
class patTemplate_TemplateCache_File extends patTemplate_TemplateCache
{
/**
* parameters of the cache
*
* @access private
* @var array
*/
var $_params = array(
'cacheFolder' => './cache',
'lifetime' => 'auto'
);
/**
* load template from cache
*
* @access public
* @param string cache key
* @param integer modification time of original template
* @return array|boolean either an array containing the templates or false cache could not be loaded
*/
function load( $key, $modTime = -1 )
{
$filename = $this->_getCachefileName( $key );
if( !file_exists( $filename ) || !is_readable( $filename ) )
return false;
$generatedOn = filemtime( $filename );
$ttl = $this->getParam( 'lifetime' );
if( $ttl == 'auto' )
{
if( $modTime < 1 )
return false;
if( $modTime > $generatedOn )
return false;
return unserialize( file_get_contents( $filename ) );
}
elseif( is_int( $ttl ) )
{
if( $generatedOn + $ttl < time() )
return false;
return unserialize( file_get_contents( $filename ) );
}
return false;
}
/**
* write template to cache
*
* @access public
* @param string cache key
* @param array templates to store
* @return boolean true on success
*/
function write( $key, $templates )
{
$fp = @fopen( $this->_getCachefileName( $key ), 'w' );
if( !$fp )
return false;
flock( $fp, LOCK_EX );
fputs( $fp, serialize( $templates ) );
flock( $fp, LOCK_UN );
return true;
}
/**
* get the cache filename
*
* @access private
* @param string cache key
* @return string cache file name
*/
function _getCachefileName( $key )
{
return $this->getParam( 'cacheFolder' ) . '/' . $key . '.cache';
}
}
?>
As you can see, implementing a template cache is really simple and should not pose a problem to the experienced PHP developer
