RayCache, A Simple and Easy PHP Caching Class with multiple configurations and plug and play features.
Ever needed a quick caching class for your PHP application? This is another caching class for PHP which is able to solve your quick caching needs. Now a days all major frameworks comes with a standard caching library. But, in some cases you may need only a caching class. It is also helpful when you are not using framework or if you don’t like the cache class provided by the framework. In my case, I am using CodeIgniter for last few months and I am not happy with the caching solution provided by CodeIgniter.
Since, I am a CakePHP lover, I have looked at CakePHP cache library and tried to make something similar. So, you may find similarity with CakePHP.
Features:
- Simple & Easy to use from anywhere in your application with a single line of code.
- Easily configurable & can work without any configuration.
- Support multiple cache configurations
- Support static method for caching
- Support file caching engine for now, other caching engines can be added to the class
- Support singleton pattern
- Light Weight
Class:
File: raycache.php
<?php
/* SVN FILE: $Id: raycache.php 85 2008-05-13 07:36:10Z rayhan $ */
/** Cache Object Class.
*
* Caching classes for easy and plug and play installation.
*
* PHP version 5+
*
*
* @copyright Copyright 2006-2010, Md. Rayhan Chowdhury
* @package raynux
* @subpackage raynux.labs.cache
* @version $Revision: 85 $
* @modifiedby $LastChangedBy: rayhan $
* @lastModified $Date: 2008-05-13 13:36:10 +0600 (Tue, 13 May 2008) $
* @author $Author: rayhan $
* @website www.raynux.com
* @license MIT License http://www.opensource.org/licenses/mit-license.php
*/
/**
* Cache Engine Interface
*
*/
Interface RayCacheEngineInterface{
function write($key, $data, $options = array());
function read($key, $options = array());
function delete($key, $options = array());
function clear($expired = true);
function gc();
public static function &getInstance($configs = array());
}
/**
* Cache Class
*
* Provide cache functionality for multiple configuration and engine.
* Static read-write method are helpful to call from anywhere of the script.
*
* @package raynux
* @subpackage raynux.labs.cache
*/
class RayCache{
/**
* Class Instances
*
* @var array
*/
private static $__instances = array();
/**
* Get Instance of a cache engine
*
* Factory Interface for Cache Engine.
*
* @param config $configName
* @param string $engine default file
* @param array $configs
* @return object
*/
public static function &getInstance($configName = null, $engine = null, $configs = array()){
if (empty($configName)) {
$configName = 'default';
}
if (empty($engine)) {
$engine = 'file';
}
if (isset(self::$__instances[$configName])) {
return self::$__instances[$configName];
}
if (empty(self::$__instances)) {
$default = true;
}
$engine = strtolower($engine);
switch ($engine){
case 'file':
default:
self::$__instances[$configName] = new RayFileCache($configs);
break;
}
return self::$__instances[$configName];
}
/**
* Static wrapper to cache write method
*
* @param string $key
* @param mixed $data
* @param array $options, array('expire' => 10), expire in seconds
* @param string $configName
* @return boolean
*/
public static function write($key, $data, $options = array(), $configName = 'default') {
$_this = self::getInstance($configName);
return $_this->write($key, $data, $options);
}
/**
* Static Wrapper to cache read method
*
* @param string $key
* @param array $options
* @param string $configName
* @return mixed
*/
public static function read($key, $options = array(), $configName = 'default') {
$_this = self::getInstance($configName);
return $_this->read($key, $options);
}
/**
* Static wrapper to cache delete mathod
*
* @param string $key
* @param array $options
* @param string $configName
* @return boolean
*/
public static function delete($key, $options = array(), $configName = 'default') {
$_this = self::getInstance($configName);
return $_this->delete($key, $options);
}
}
/**
* File Cache Engine
*
* @package raynux
* @subpackage raynux.labs.cache
*/
class RayFileCache implements RayCacheEngineInterface{
/**
* Class Instances
*
* @var array
*/
private static $__instance;
/**
* Runtime Configuration Data
*
* @var array
*/
protected $_configs = array();
/**
* Class Constructor
*
* @param array $configs
*/
function __construct($configs = array()) {
$this->config($configs);
// run garbage collection
if (rand(1, $this->_configs['gc']) === 1) {
$this->gc();
}
}
/**
* Get Instance of Class
*
* @param string $name
* @param array $configs
* @return object
* @static
*/
public static function &getInstance($configs = array()){
if (is_null(self::$__instance)) {
self::$__instance = new self($configs);
}
return self::$__instance;
}
/**
* Set Configuration
*
* default: array('path' => './cache/', 'prefix' => 'raycache_', 'expire' => 10, 'gc' => 100)
*
* @param array $configs
* @return object self instance
*/
function &config($configs = array()) {
// default path modified to work with ci cache
$default = array('path' => './cache/', 'prefix' => 'raycache_', 'expire' => 10, 'gc' => 100);
$this->_configs = array_merge($default, $configs);
return $this;
}
/**
* Write data to cache
*
* @param string $key
* @param mixed $data
* @param array $options
* @return boolean
*/
public function write($key, $data, $options = array()){
// check is writable
if (!is_writable($this->_configs['path'])) {
echo $this->_configs['path'];
return false;
}
// Prepare data for writing
if (!empty($options['expire'])) {
$expire = $options['expire'];
} else {
$expire = $this->_configs['expire'];
}
if (is_string($expire)) {
$expire = strtotime($expire);
} else {
$expire = time() + $expire;
}
$data = serialize(array('expire' => $expire, 'data' => $data));
$fileName = $this->_configs['path'] . $this->_configs['prefix'] . $key;
// Write data to files
if (file_put_contents($fileName, $data, LOCK_EX)) {
return true;
} else {
return false;
}
}
/**
* Read Data from cache
*
* @param string $key
* @param array $options
* @return mixed
*/
public function read($key, $options = array()) {
$fileName = $this->_configs['path'] . $this->_configs['prefix'] . $key;
if (!file_exists($fileName)) {
return false;
}
if (!is_readable($fileName)) {
return false;
}
$data = file_get_contents($fileName);
if ($data === false) {
return false;
}
$data = unserialize($data);
if ($data['expire'] < time()) {
$this->delete($key);
return false;
}
return $data['data'];
}
/**
* Delete a cache data
*
* @param string $key
* @param arrayt $options
* @return boolean
*/
function delete($key, $options = array()) {
$fileName = $this->_configs['path'] . $this->_configs['prefix'] . $key;
if (!file_exists($fileName) || !is_writable($fileName)) {
return false;
}
return unlink($fileName);
}
/**
* Clear cache data
*
* @param boolean $expired if true then only delete expired cache
* @return booelan
*/
public function clear($expired = true) {
$entries = glob($this->_configs['path'] . $this->_configs['prefix'] . "*");
if (!is_array($entries)) {
return false;
}
foreach ($entries as $item) {
if (!is_file($item) || !is_writable($item)) {
continue;
}
if ($expired) {
$expire = file_get_contents($item, null, null, 20, 11);
$strpos = strpos($expire, ';');
if ($strpos !== false) {
$expire = substr($expire, 0, $strpos);
}
if ($expire > time()) {
continue;
}
}
if (!unlink($item)) {
return false;
}
}
return true;
}
/**
* Garbage collection
*
* @return boolean
*/
public function gc() {
return $this->clear(true);
}
}
?>
Usage Example: some quick examples are given below to introduce you with the class and it’s methods.
<?php
/**
* Load the cache library
*
*/
include_once('raycache.php');
/**
* Class Example
*
* Once loaded you can use this class in two ways:
* - Using Static Methods (My Favorite)
* - Using Class Instance
*
* or, even you can mix them both
* In both ways it support multiple configuration and uses
*/
/**
* Static Method
*/
//Get default CacheInstance with one of the following methods
RayCache::getInstance();
// OR
RayCache::getInstance(null, null, array('path' => 'my_cache_path/', 'prefix' => 'my_cache_', 'expire' => '+10 seconds'));
// You can configure or reconfigure your instance anytime you like.
RayCache::getInstance()->config(array('path' => 'my_cache_path/', 'prefix' => 'my_cache_', 'expire' => '+10 seconds'));
// store data
RayCache::write('test_key', 'This data will expire in 10 seconds
');
RayCache::write('test_key2', 'This data will expire in 10 seconds
', array('expire' => '+10 seconds')); // expre value can be integer in seconds or time string supported by php strtotime method
RayCache::write('test_key3', 'This data will expire in 20 seconds
', array('expire' => '+20 seconds'));
// read data
echo RayCache::read('test_key');
echo RayCache::read('test_key2');
echo RayCache::read('test_key3');
/**
* Class Instance Method
*/
// get calss class instance
$cache = RayCache::getInstance(); // default configure
$cache2 = RayCache::getInstance('short', null, array('prefix' => 'short_', 'path' => 'my_cache_path/', 'expire' => '+20 seconds'));
$cache3 = RayCache::getInstance('long', null, array('prefix' => 'long_', 'path' => 'my_cache_path/', 'expire' => '+1 hour'));
// store data
$cache->write('test_key', 'This data will expire in 10 seconds
');
$cache2->write('test_key2', 'This data will expire in 20 seconds
');
$cache3->write('test_key3', 'This data will expire in 1 hour
');
// read data
echo $cache->read('test_key');
echo $cache2->read('test_key2');
echo $cache3->read('test_key3');
?>
Please let me know if you find this class helpful for you..