I've found the PHPLIB template class to be very useful for seperating code from logic.
After putting a lot of thought into how I can allow my current site to cache dynamic pages, I decided to extend the Template class to do it for me.
For use of the template class, please see the article http://www.phpbuilder.com/columns/david20000512.php3
On my pages, I call the pparse("parseIntoVar", "parseVar") function at the very end of my scripts. This function parses the template variable parseVar into parseIntoVar and print()'s the result. By caching my dynamic page at this point, I will only need to change my initialization of my template variable and add one call to a new function set_cache() on any page I want cached.
Four new instance variables are needed. They should all be concidered private variables.
They are:
/* for caching pages */
var $refreshCache = false;
var $cacheName = "";
var $cachePath = "/tmp/";
/* default = 15 min */
var $cacheTimeout = 900;
The new pparse() function stores the returned value from parse() long enough to write it to a file (cache object) the prints it.
/**
* Override the ancestor function so we can save the parse result
*/
function pparse($target, $handle, $append = false) {
$str = $this->parse($target, $handle, $append);
// For caching
if ($this->refreshCache) error_log($str, 3, $this->cachePath . $this->cacheName);
print $str;
return false;
}
Finally the new function, set_cache():
/**
* set_cache ( array or string )
*
* Parameter: array or cache file name
*
* set_cache(array("name" => "cache file name",
* "path" => "cache file path",
* "timeout" => seconds before refresh));
*
* or set_cache("cache file name");
*/
function set_cache($cacheParms) {
if (is_array($cacheParms)) {
// Set name and the path to the cached file
$this->cacheName = $cacheParms["name"];
if ($cacheParms["path"]) $this->cachePath = $cacheParms["path"];
// Set timeout to 15 min. if not specified
if ($cacheParms["timeout"]) $this->cacheTimeout = $cacheParms["timeout"];
} else {
$this->cacheName = $cacheParms;
}
if (!$this->cacheName) return false;
// Get the last modified time for the file
## lstat[9] = FILE_LASTUPDATE
$fileProps = lstat($this->cachePath . $this->cacheName);
// Set the refresh cache to true if our delta is too big
if ($this -> refreshCache = ((time() - $fileProps[9]) > $this->cacheTimeout)) {
// Delete the cached file
@unlink($this->cachePath . $this->cacheName);
} else {
// Use the cached file
include ($this->cachePath . $this->cacheName);
die();
}
}
"name" => $string and can contain either of:
"path" => "cache file path"
"timeout" => seconds before refresh
Finally, a simple script with before and after cache implementation:
Before:
<?
include ("template.inc");
$t = new template("/templates");
$t -> set_file("main", "index.ihtml");
$t -> pparse("output", "main");
?>
<?
include ("template.inc");
include ("c_template.inc");
$t = new c_template("/templates");
$t -> set_cache(array("name" => "cachetest", "timeout" => 10, "path" => "/tmp/"));
$t -> set_file("main", "index.ihtml");
$t -> pparse("output", "main");
?>
Finally, here is the assembeled class:
class c_Template extends Template {
/* for caching pages */
var $refreshCache = false;
var $cacheName = "";
var $cachePath = "/tmp/";
/* default = 15 min */
var $cacheTimeout = 900;
/**
* Override the ancestor function so we can save the parse result
*/
function pparse($target, $handle, $append = false) {
$str = $this->parse($target, $handle, $append);
// For caching
if ($this->refreshCache) error_log($str, 3, $this->cachePath . $this->cacheName);
print $str;
return false;
}
/**
* set_cache ( array or string )
*
* Parameter: array or cache file name
*
* set_cache(array("name" => "cache file name",
* "path" => "cache file path",
* "timeout" => seconds before refresh));
*
* or set_cache("cache file name");
*/
function set_cache($cacheParms) {
if (is_array($cacheParms)) {
// Set name and the path to the cached file
$this->cacheName = $cacheParms["name"];
if ($cacheParms["path"]) $this->cachePath = $cacheParms["path"];
// Set timeout to 15 min. if not specified
if ($cacheParms["timeout"]) $this->cacheTimeout = $cacheParms["timeout"];
} else {
$this->cacheName = $cacheParms;
}
if (!$this->cacheName) return false;
// Get the last modified time for the file
## lstat[9] = FILE_LASTUPDATE
$fileProps = lstat($this->cachePath . $this->cacheName);
// Set the refresh cache to true if our delta is too big
if ($this -> refreshCache = ((time() - $fileProps[9]) > $this->cacheTimeout)) {
// Delete the cached file
@unlink($this->cachePath . $this->cacheName);
} else {
// Use the cache
include ($this->cachePath . $this->cacheName);
die();
}
}
}
This has worked wonderfully for me, and I hope it others can find it just as useful. - Tom