Quantcast
Channel: Rayhan's blog (raynux.com) » class
Viewing all articles
Browse latest Browse all 2

RayCache – An Easy, Multiple Configurable PHP Caching Class

$
0
0

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'] 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..


Viewing all articles
Browse latest Browse all 2

Latest Images

Trending Articles





Latest Images