<? Online-PHP::Tutorials ?>

« Back

  • Caching Class

     

    Intro

     
    Actually, I have taken the implementation from here, modified it a little bit:
    • Added default TTL to a month
    • Made a singleton class
    • Created a method which returns / checks if the cache directory exists

     

    The code

    class FileCache {
     
        static private $instance = NULL;
     
        private function __construct() {
            
        }
     
        static private function get_instance() {
            if (is_null(self::$instance)) {
                self::$instance = new FileCache();
            }
            return self::$instance;
        }
     
        // This is the function you store information with
        static public function store($key, $data, $ttl = null) {
     
            // set the default TTL to a month
            if (is_null($ttl)) {
                $ttl = 30 * 24 * 60 * 60;
            }
     
            $_this = self::get_instance();
     
            // Opening the file
            $h = fopen($_this->getFileName($key), 'w');
            if (!$h) {
                throw new Exception('Could not write to cache');
            }
            
            // Serializing along with the TTL
            $data = serialize(array(time() + $ttl, $data));
            if (fwrite($h, $data) === false) {
                throw new Exception('Could not write to cache');
            }
            fclose($h);
        }
     
        static public function clear($key) {
            $_this = self::get_instance();
            $filename = $_this->getFileName($key);
            if (file_exists($filename)) {
                @unlink($filename);
            }
        }
     
        private $cache_dir_name = NULL;
     
        private function _check_directory_exists() {
            if (is_null($this->cache_dir_name)) {
                $this->cache_dir_name = dirname(__FILE__) . '/_cache';
            }
            if (!is_dir($this->cache_dir_name)) {
                mkdir($this->cache_dir_name, true);
            }
        }
     
        // General function to find the filename for a certain key
        private function getFileName($key) {
            $_this = self::get_instance();
            $_this->_check_directory_exists();
            return $_this->cache_dir_name . '/s_cache' . md5($key);
        }
     
        // The function to fetch data returns false on failure
        static public function fetch($key) {
            $_this = self::get_instance();
            $filename = $_this->getFileName($key);
            if (!file_exists($filename) || !is_readable($filename))
                return false;
     
            $data = file_get_contents($filename);
     
            $data = @unserialize($data);
            if (!$data) {
     
                // Unlinking the file when unserializing failed
                unlink($filename);
                return false;
            }
     
            // checking if the data was expired
            if (time() > $data[0]) {
     
                // Unlinking
                unlink($filename);
                return false;
            }
            return $data[1];
        }
     
    }
     

    Summary

     
    It's simple, useful and lightweight. You can feel free to use it.
     
    Enjoy,
    Gregory C.