Writing Your Own Template Caching Class In PHP - The Code Explained (contd.) (Page 4 of 6 ) if (is_file($filename)) { clearstatcache();
if (filemtime($filename) > (time() - $this->_cacheLifetime)) { $isCached = true; } } The first "if" construct simply checks if the file exists. The second if construct checks if the time since the file was last modified is greater than $_cacheLifetime. Let's move on to the _addCache() method. This method simply creates a cache file: function _addCache($content, $file, $id = false) { $id = $id ? md5($id . basename($file)) : md5(basename($file)); $filename = $this->_cacheDir . '/' . $id . '/' . basename($file); $directory = $this->_cacheDir . '/' . $id;
@mkdir($directory, 0775);
if ($fp = fopen($filename, 'wb')) { fwrite($fp, $content); fclose($fp); } } As you can see, this code snippet is pretty similar to the code in the isCached() method. @mkdir($directory, 0775); The above function call simply creates the directory for the cache item. if ($fp = fopen($filename, 'wb')) { fwrite($fp, $content); fclose($fp); } This code opens a stream to the cache file (which is created there and then), and writes everything inside $content to the file. There's actually only one method left before the class is finished. The last method we'll add is _getCache(). This method is used for retrieving the content of a cache file: function _getCache($file, $id = false) { $id = $id ? md5($id . basename($file)) : md5(basename($file)); $filename = $this->_cacheDir . '/' . $id . '/' . basename($file);
if ($fp = fopen($filename, 'rb')) { $content = fread($fp, filesize($filename)); fclose($fp); }
return isset($content) ? $content : false; } Here's the only differing part from the last function: if ($fp = fopen($filename, 'rb')) { $content = fread($fp, filesize($filename)); fclose($fp); }
return isset($content) ? $content : false; This code simply opens a stream to the cache fil, and reads it all into a variable. The variable is then returned. That's it! The class is now finished. The Whole Class Here's the whole class in one part. Just in case you're in a hurry: <?php
class Template {
var $_variables = array(); var $_caching = false; var $_cacheDir = '/cache'; var $_cacheLifetime = 120;
function addVar($name, $value) { $variables = &$this->_variables; $variables[$name] = $value; }
function display($file, $id = false) { echo $this->fetch($file, $id); }
function fetch($file, $id = false) { if ($this->_caching == true && $this->isCached($file, $id)) { $output = $this->_getCache($file, $id); } else { $output = $this->_getOutput($file);
if ($this->_caching == true) { $this->_addCache($output, $file, $id); } }
return isset($output) ? $output : false; }
function _getOutput($file) { extract($this->_variables); $file = realpath($file);
if (file_exists($file)) { ob_start(); include($file); $output = ob_get_contents(); ob_end_clean(); } else { trigger_error("Failed opening the template file '$file'. The file doesn't exist.", E_USER_ERROR); }
return !empty($output) ? $output : false; }
function setCacheDir($dir) { $dir = realpath($dir);
if (is_dir($dir) && is_writable($dir)) { $this->_cacheDir = $dir; } else { trigger_error("The cache directory '$dir' either doesn't exist, or it cannot be written to by PHP", E_USER_WARNING); $this->_cacheDir = ''; $this->_caching = false; } }
function setCacheLifetime($seconds) { if (is_numeric($seconds)) { $this->_cacheLifetime = $seconds; } }
function setCaching($state) { if (is_bool($state)) { $this->_caching = $state; } }
function isCached($file, $id = false) { $id = $id ? md5($id . basename($file)) : md5(basename($file)); $filename = $this->_cacheDir . '/' . $id . '/' . basename($file);
if (is_file($filename)) { clearstatcache();
if (filemtime($filename) > (time() - $this->_cacheLifetime)) { $isCached = true; } }
return isset($isCached) ? true : false; }
function _addCache($content, $file, $id = false) { $id = $id ? md5($id . basename($file)) : md5(basename($file)); $filename = $this->_cacheDir . '/' . $id . '/' . basename($file); $directory = $this->_cacheDir . '/' . $id;
@mkdir($directory, 0775);
if ($fp = fopen($filename, 'wb')) { fwrite($fp, $content); fclose($fp); } }
function _getCache($file, $id = false) { $id = $id ? md5($id . basename($file)) : md5(basename($file)); $filename = $this->_cacheDir . '/' . $id . '/' . basename($file);
if ($fp = fopen($filename, 'rb')) { $content = fread($fp, filesize($filename)); fclose($fp); }
return isset($content) ? $content : false; } }
?> I'll now show you a few examples on advanced usage of this class in real-world PHP applications. Next: Real-World Examples >>
More MySQL Articles More By Havard Lindset |