phpI have been working on a small class to cache functions in PHP. I have come up with a class that will allow you to convert any standard function into a cached function with just one line of code. The main advantage is if you are using a Linux based server for running PHP, as I have included (by default) for the cache files to write straight to the system RAM that greatly increases performance. Check out the code below.

This is the first release of the file up to now so if you have any problems let me know.

<?php
/**
 * PHPCache Class
 *
 * @desc Simple class to cache PHP function output to speed
 *		 up code. Creates a cache file of the MD5'd function
 *       parameters in a seperate folder for the function.
 *		 Also has optional write to RAM on Linux machines.
 *
 *		 See examples.php for usage.
 *
 * @author Steve McMillan <steve.mcmillan@elite-fx.net>
 * @created   03/12/2009 11:31AM
 * @credits Alex G (original caching functions)
 *
 */
class PHPCache {
    public $cacheTimeout = 600;
    public $cacheExtension = '.phpcache';
    private $ramAvailable = false;
    private $baseDir = 'cache';

    function __construct($cacheDir = '', $useRAM = true) {
        if ($useRAM) {
			//Is the server capable of using RAM access
            $this->ramAvailable = $this->__ramAvailable();
        }

        if ($cacheDir == '') {
            if ($this->ramAvailable) {
                $this->baseDir = '/dev/shm/'.$this->baseDir;
            } else {
                $this->baseDir = getCwd().'/'.$this->baseDir;
            }
        }
		//Make sure the baseDir exists.
        $this->setupDirs();
    }

    public function getCache($func, $params = null, $time = 0) {
        if ($time != 0) {
            $this->cacheTimeout = $time;
        }

        $cacheKey = md5(serialize($params).$_SERVER['HTTP_HOST']);

        if (is_array($func)) {
            $cacheDir = $this->baseDir.'/'.$func[1];
        } else {
            $cacheDir = $this->baseDir.'/'.$func;
        }

        $cacheFile = $cacheDir.'/'.$cacheKey.$this->cacheExtension;

        if (!is_dir($cacheDir)) {
            if (!mkdir($cacheDir, 0770)) {
                return call_user_func_array($func, $params);
            }
        }

        if (file_exists($cacheFile)) {
            if ((time() - filemtime($cacheFile)) < $this->cacheTimeout) {
                return unserialize(file_get_contents($cacheFile));
            }
        }

        $out = call_user_func_array($func, $params);
        file_put_contents($cacheFile, serialize($out));
        return $out;
    }

    private function __ramAvailable() {
        if (PHP_OS == 'Linux') {
            if (is_writable('/dev/shm')) {
                return true;
            }
        }
        return false;
    }

    private function setupDirs() {
        if (isset($this->baseDir)) {
            if (!is_dir($this->baseDir)) {
                mkdir($this->baseDir, 0770);
            }
        }
    }

    public function microtime_float() {
        list($usec, $sec) = explode(' ', microtime());
        return ((float) $usec + (float) $sec);
    }

    public function clearCache($func) {
        if ($func == 'ALL') {
            if (file_exists($this->baseDir)) {
                $this->delTree($this->baseDir);
            }
        } else {
            if (file_exists($this->baseDir.'/'.$func)) {
                $this->delTree($this->baseDir.'/'.$func);
            }
        }
    }

    private function delTree($dir) {
        $files = glob($dir.'*', GLOB_MARK);
        foreach ($files as $file) {
            if (substr($file, -1) == '/') {
                $this->delTree($file);
            } else {
                unlink($file);
            }
        }
        if (is_dir($dir))
            rmdir($dir);
    }
}
?>

Shown below is sample usage in a basic PHP application, we first include and start up the new class and then use the $cache->getCache to call our cached function.

 <?php
	include('phpcache.php');
	$cache = new PHPCache();

	echo $cache->getCache('function', Array('parameter'));
?>

If you require the function to be called inside another class, change the first parameter into an array, like so (where $this is the class object);

echo $cache->getCache(array($this, 'function'), array('parameter'));

The class should make the directory structure for you, if not – Please make sure the script has sufficient permissions to be able to read/write from the cache folder location. If you need to change the default cache folder see the variable at the top of the class. You can also set $cache->cacheTimeout (time is in seconds) the default is 600 seconds (10 minutes)

If you are not using the RAM storage in Linux and would like to clear your cache files I have built in a function to do it, just call $cache->clearCache(‘function’); for a single cache clear or $cache->clearCache(‘ALL’); to clear all the cache files at once.

Big thanks to Alex G who shown me his awesome caching system, from which this was built from.

If you wish you can download the files; get them from here: Download PHPCache