PX : code

CachedFastTemplate class by Jesus M. Castagnetto
Download this code


NOTE: separate the 2 files before testing

::::::::::::::
class.CachedFastTemplate.php
::::::::::::::
<?php

/*
 * Class CachedFastTemplate
 * by Jesus M. Castagnetto (jesusmc@scripps.edu)
 * (c) 2000. Version 1.1
 *
 * Description:
 * This class extends CDI's (cdi@thewebmasters.net) FastTemplate class,
 * implementing methods to cache the output to a file. This would be
 * useful for cases in which a template is used for both, the static
 * pages in a web site, and pages created from PHP scripts. In this
 * way we will avoid processing pages that do not change too often.
 *
 * Changes:
 * 2000/06/06 - Merged in some modifications submitted by Aaron Bush
 *              (AB) <abush@microcenter.com>. In fact he sent
 *              these some time ago, and I finally unearth them from
 *              my filesystem. Mainly changed to recognize if the
 *              the file calling this class or the templates have 
 *              been modified.
 * 2000/06/07 - Added some logic, so the same template can be used for
 *              storing a cached template for seconds/minutes/hours/days
 *              added 2 new methods: set_time_unit and _is_valid_time_unit,
 *              and renamed internal methods (the ones with names prefixed
 *              by "_"), from _mkdatestamp to _mktimestamp, and from
 *              _diff_days to _diff_time, renamed/modified also some internal
 *              variables in methods.
 * 
 */


class CachedFastTemplate extends FastTemplate {

    var 
$CACHEDIR "./cache";      // directory to save cached files
    
var $CACHELENGTH 30;          // length of caching, 30 units.
    
var $TIMEUNIT "day";            // time unit
    
var $TIMEUNITSARR = array ("sec"=>1"min"=>60"hour"=>3600"day"=>86400);

    function 
CachedFastTemplate($path_to_tpls=""$cdir=""$clen="") {
        
$this->FastTemplate($path_to_tpls);
        if (!empty(
$cdir)) {
            
$this->set_cache_dir($cdir);
        }
        if (!empty(
$clen)) {
            
$this->set_cache_length($clen);
        }
    }

    function 
set_cache_dir($dir) {
        if (
substr($dir,(strlen($dir) - 1), 1) == "/") {
            
$dir substr($dir,0,-1);
        }
        
$this->CACHEDIR $dir;
    }

    function 
set_cache_length($length) {
        
$this->CACHELENGTH $length;
    }

    function 
write_to_cache($filename=""$content="") {
        global 
$PHP_SELF;
        if (empty(
$filename)) {
            
$filename str_replace("/""_"$PHP_SELF);
        }
        if (empty(
$content)) {
            
$content $this->fetch();
        }
        
// write the contents
        
$fp fopen($this->CACHEDIR."/".$filename.".cache""w");
        
fwrite($fp,$content);
        
fclose($fp);
        
// write the cache control file
        
$timestamp $this->_mktimestamp();
        
$fp fopen($this->CACHEDIR."/".$filename.".cntrl""w");
        
fwrite($fp$timestamp.":".$this->CACHELENGTH);
        
fclose($fp);
    }

    function 
read_from_cache($filename="") {
        global 
$PHP_SELF;
        if (empty(
$filename)) {
            
$filename str_replace("/""_"$PHP_SELF);
        }
        if (
$this->is_cached($filename)) {
            
readfile($this->CACHEDIR."/".$filename.".cache");
            return 
true;
        } else {
            return 
false;
        }
    }

    function 
is_cached($filename) {
        return (
is_file($this->CACHEDIR."/".$filename.".cache") &&
                
is_file($this->CACHEDIR."/".$filename.".cntrl"));
    }

    function 
valid_cache_file($filename="") {
        global 
$PHP_SELF$PATH_TRANSLATED;        // for new logic (AB)
        
if (empty($filename)) {
            
$filename str_replace("/""_"$PHP_SELF);
        }
        if (
$this->is_cached($filename)) {
            
$info file($this->CACHEDIR."/".$filename.".cntrl");
            
$val explode(":"$info[0]);
            
// the following block from (AB)
            // check fileHandles time vs. control time
             
if (filemtime($PATH_TRANSLATED) >= $val[0])
                 return 
false;
             if (
count($this->FILELIST) > ) {
                 while (list(
$tag$fn) = each($this->FILELIST)) {
                     if ( 
is_file($this->ROOT.$fn) &&
                         (
filemtime($this->ROOT.$fn) >= $val[0]) )
                             return 
false;
                 }
             }
             
// end check fileHandles
 
            
$today $this->_mktimestamp();
            return ( 
$this->_diff_time($today$val[0]) <= $val[1] );
        } else {
            return 
false;
        }
    }

    function 
set_time_unit($str) {
        if (
$this->_is_valid_time_unit($str)) {
            
$this->TIMEUNIT $str;
        } else {
            
$this->TIMEUNIT "day";
        }
    }

    function 
_is_valid_time_unit($str) {
        while (list(
$key$val) = each($this->TIMEUNITSARR)) {
            if (
$key == $str)
                return 
true;
        }
        return 
false;
    }    

    function 
_mktimestamp() {
        return 
time();
    }

    function 
_diff_time($end$start) {
        
$factor $this->TIMEUNITSARR[$this->TIMEUNIT];
        return 
intval(($end $start)/$factor);
    }

// end of class definition
?>
::::::::::::::
test.php
::::::::::::::
<?php
// This test file is a simple modification of a
// sample file include in FastTemplate

require ("./class.FastTemplate.php3");
require (
"./class.CachedFastTemplate.php");

$tpl = new CachedFastTemplate("./templates");

// for benchmarking
$start $tpl->utime();

$filename "yipeee.html";
// if the filename is empty, the class will use PHP_SELF

// the templates are distributed w/FastTemplate
// we need this definition first, so the new logic can
// detect if the templates have changed.
$tpl->define(
    array(
        
main    => "main.tpl",
        
table   => "table.tpl",
        
row     => "row.tpl"
    
)
);


// Check if we can send the cached file
if ($tpl->valid_cache_file($filename)) {
    echo 
"<B>FROM CACHE</B>\n<BR>";
    
$tpl->read_from_cache($filename);
    
$end $tpl->utime();
    
$runtime = ($end $start) * 1000;
    echo 
"Completed in $runtime miliseconds<BR>\n";
    exit;
}

// Otherwise process the page
$tpl->assign( array( TITLE => "FastTemplate Test") );

for (
$n=1$n <= 3$n++)
{
    
$Number $n;
    
$BigNum $n*10;

    
$tpl->assign(
        array(
            
NUMBER      =>  $Number,
            
BIG_NUMBER  =>  $BigNum
        
)
    );

    
$tpl->parse(ROWS,".row");
}

$tpl->parse(MAIN, array("table","main"));

$data $tpl->fetch();
$tpl->write_to_cache($filename$data);

$tpl->FastPrint();

// for benchmarking
$end $tpl->utime();
$runtime = ($end $start) * 1000;
echo 
"Completed in $runtime miliseconds<BR>\n";
exit;

?>

Comments or questions?
PX is running PHP 5.2.17
Thanks to Miranda Productions for hosting and bandwidth.
Use of any code from PX is at your own risk.