首页  >  文章  >  后端开发  >  PHP比较全面的缓存类

PHP比较全面的缓存类

巴扎黑
巴扎黑原创
2016-11-24 15:12:041103浏览

/*

* Name: wrapperCache

* Notes: wrapper cache for fileCache, memcache/memcached, APC, Xcache and eaccelerator

$cacheObj =wrapperCache::getInstance('memcache',30,array(array('host'=>'localhost')));

echo $cacheObj->cache('key','value');

*/

class wrapperCache {

    const DEFAULT_MEMCACHE_PORT     = 11211;


    const CACHE_TYPE_AUTO           = 'auto';

    const CACHE_TYPE_EACCELERATOR   = 'eaccelerator';

    const CACHE_TYPE_APC            = 'apc';

    const CACHE_TYPE_MEMCACHE       = 'memcache';

    const CACHE_TYPE_MEMCACHED      = 'memcached';

    const CACHE_TYPE_FILE           = 'filecache';

    const CACHE_TYPE_XCACHE         = 'xcache';


    private $cache_params;   //extra params for external caches like path or connection option memcached

    public  $cache_expire;   //seconds that the cache expires

    private $cache_type;     //type of cache to use

    private $cache_external; //external instance of cache, can be fileCache or memcache

    private static $instance;//Instance of this class


    // Always returns only one instance

    public static function getInstance($type=self::CACHE_TYPE_AUTO, $exp_time=3600, $params='cache/'){

        if (!isset(self::$instance)) { //doesn't exists the isntance

            self::$instance = new self($type, $exp_time, $params); //goes to the constructor

        }

        return self::$instance;

    }


    //cache constructor, optional expiring time and cache path

    private function __construct($type, $exp_time, $params) {

        $this->cache_expire = $exp_time;

        $this->cache_params = $params;

        $this->setCacheType($type);

    }


    public function __destruct() {

        unset($this->cache_external);

    }


    // Prevent users to clone the instance

    public function __clone(){

        $this->cacheError('Clone is not allowed.');

    }


    //deletes cache from folder

    public function clearCache(){

        switch($this->cache_type){

            case self::CACHE_TYPE_EACCELERATOR :

                eaccelerator_clean();

                eaccelerator_clear();

                break;


            case self::CACHE_TYPE_APC :

                apc_clear_cache('user');

                break;


            case self::CACHE_TYPE_XCACHE :

                xcache_clear_cache(XC_TYPE_VAR, 0);

                break;


            case self::CACHE_TYPE_MEMCACHE :

                $this->cache_external->flush();

                break;


            case self::CACHE_TYPE_MEMCACHED :

                $this->cache_external->flush();

                break;


            case self::CACHE_TYPE_FILE:

                $this->cache_external->deleteCache();

                break;

        }

    }


    //writes or reads the cache

    public function cache($key, $value = '', $ttl = '') {

        if ($value != '') { //wants to write

            if ($ttl == '') $ttl = $this->cache_expire;

            $this->put($key, $value, $ttl);

        } else return $this->get($key);

        //reading value

    }


    //creates new cache files with the given data, $key== name of the cache, data the info/values to store

    private function put($key, $data, $ttl = '') {

        if ($ttl == '') $ttl = $this->cache_expire;


        switch($this->cache_type){

            case self::CACHE_TYPE_EACCELERATOR :

                eaccelerator_put($key, serialize($data), $ttl);

                break;


            case self::CACHE_TYPE_APC :

                apc_store($key, $data, $ttl);

                break;


            case self::CACHE_TYPE_XCACHE :

                xcache_set($key, serialize($data), $ttl);

                break;


            case self::CACHE_TYPE_MEMCACHE :

                $data=serialize($data);

                $this->cache_external->set($key, $data, false, $ttl);

                break;


            case self::CACHE_TYPE_MEMCACHED :

                $data=serialize($data);

                $this->cache_external->set($key, $data, $ttl);

                break;


            case self::CACHE_TYPE_FILE :

                $this->cache_external->cache($key,$data);

                break;

        }

    }


    //returns cache for the given key

    private function get($key){

        switch($this->cache_type){

            case self::CACHE_TYPE_EACCELERATOR :

                $data =  unserialize(eaccelerator_get($key));

                break;


            case self::CACHE_TYPE_APC :

                $data =  apc_fetch($key);

                break;


            case self::CACHE_TYPE_XCACHE :

                $data =  unserialize(xcache_get($key));

                break;


            case self::CACHE_TYPE_MEMCACHE :

                $data = unserialize($this->cache_external->get($key));

                break;


            case self::CACHE_TYPE_MEMCACHED :

                $data = unserialize($this->cache_external->get($key));

                break;


            case self::CACHE_TYPE_FILE :

                $data = $this->cache_external->cache($key);

                break;

        }

        return $data;

    }


    //delete key from cache

    public function delete($key){

        switch($this->cache_type){

            case self::CACHE_TYPE_EACCELERATOR :

                eaccelerator_rm($key);

                break;


            case self::CACHE_TYPE_APC :

                apc_delete($key);

                break;


            case self::CACHE_TYPE_XCACHE :

                xcache_unset($key);

                break;


            case self::CACHE_TYPE_MEMCACHE :

                $this->cache_external->delete($key);

                break;


            case self::CACHE_TYPE_MEMCACHED :

                $this->cache_external->delete($key);

                break;


            case self::CACHE_TYPE_FILE :

                $this->cache_external->delete($key);

                break;

        }


    }

    // Overloading for the Application variables and automatically cached

    public function __set($name, $value) {

        $this->put($name, $value, $this->cache_expire);

    }


    public function __get($name) {

        return $this->get($name);

    }


    public function __isset($key) {//echo "Is '$name' set?\n"

        if ($this->get($key) !== false)  return true;

        else return false;

    }


    public function __unset($name) {//echo "Unsetting '$name'\n";

        $this->delete($name);

    }

    //end overloads


    public function getCacheType(){

        return $this->cache_type;

    }


    //sets the cache if its installed if not triggers error

    public function setCacheType($type){

        $this->cache_type=strtolower($type);


        switch($this->cache_type){

            case self::CACHE_TYPE_EACCELERATOR :

                if (!function_exists('eaccelerator_get')) $this->cacheError('eaccelerator not found');

                break;


            case self::CACHE_TYPE_APC :

                if (!function_exists('apc_fetch')) $this->cacheError('APC not found');

                break;


            case self::CACHE_TYPE_XCACHE :

                if (function_exists('xcache_get')) $this->cacheError('Xcache not found');

                break;


            case self::CACHE_TYPE_MEMCACHE :

                if (class_exists('Memcache')) $this->init_mem();

                else $this->cacheError('memcache not found');

                break;


            case self::CACHE_TYPE_MEMCACHED :

                if (class_exists('Memcached')) $this->init_mem(true);

                else $this->cacheError('memcached not found');

                break;


            case self::CACHE_TYPE_FILE :

                if (class_exists('fileCache'))$this->init_filecache();

                else $this->cacheError('fileCache not found');

                break;


            case self::CACHE_TYPE_AUTO ://try to auto select a cache system

                if (function_exists('eaccelerator_get'))    $this->cache_type = self::CACHE_TYPE_EACCELERATOR;

                elseif (function_exists('apc_fetch'))       $this->cache_type = self::CACHE_TYPE_APC ;

                elseif (function_exists('xcache_get'))      $this->cache_type = self::CACHE_TYPE_XCACHE;

                elseif (class_exists('Memcache'))           $this->init_mem();

                elseif (class_exists('Memcached'))          $this->init_mem(true);

                elseif (class_exists('fileCache'))          $this->init_filecache();

                else $this->cacheError('not any compatible cache was found');

                break;


            default://not any cache selected or wrong one selected

                $msg='Not any cache type selected';

                if (isset($type)) $msg='Unrecognized cache type selected '.$type.'';

                $this->cacheError($msg);

                break;

        }

    }


    private function init_mem($useMemecached = false) { //get instance of the memcache/memcached class

        if (is_array($this->cache_params)) {

            if ($useMemecached) {

                $this->cache_type = self::CACHE_TYPE_MEMCACHED;

                $this->cache_external = new Memcached();

            } else {

                $this->cache_type = self::CACHE_TYPE_MEMCACHE;

                $this->cache_external = new Memcache;

            }

            foreach ($this->cache_params as $server) {

                $server['port'] = isset($server['port']) ? (int)$server['port'] : self::DEFAULT_MEMCACHE_PORT;

                if ($useMemecached) {

                    $this->cache_external->addServer($server['host'], $server['port']);

                } else {

                    $server['persistent'] = isset($server['persistent']) ? (bool)$server['persistent'] : true;

                    $this->cache_external->addServer($server['host'], $server['port'], $server['persistent']);

                }

            }

        } else $this->cacheError($this->cache_type . ' needs an array, example:wrapperCache::getInstance("' . $this->cache_type . '",30,array(array("host"=>"localhost")));');

    }


    private function init_filecache(){//get instance of the filecache class

        $this->cache_type = self::CACHE_TYPE_FILE ;

        $this->cache_external = fileCache::getInstance($this->cache_expire, $this->cache_params);

    }


    public function getAvailableCache($return_format='html'){//returns the available cache

        $avCaches   = array();

        $avCaches[] = array(self::CACHE_TYPE_EACCELERATOR,function_exists('eaccelerator_get'));

        $avCaches[] = array(self::CACHE_TYPE_APC,         function_exists('apc_fetch')) ;

        $avCaches[] = array(self::CACHE_TYPE_XCACHE,      function_exists('xcache_get'));

        $avCaches[] = array(self::CACHE_TYPE_MEMCACHE,    class_exists('Memcache'));

        $avCaches[] = array(self::CACHE_TYPE_MEMCACHED,   class_exists('Memcached'));

        $avCaches[] = array(self::CACHE_TYPE_FILE,        class_exists('fileCache'));


        if ($return_format == 'html') {

            $ret = '

    ';

                foreach ($avCaches as $c) {

                    $ret .= '

  • ' . $c[0] . ' - ';

                    if ($c[1]) $ret .= 'Found/Compatible';

                    else $ret .= 'Not Found/Incompatible';

                    $ret .= '';

                }

                return $ret . '

';

        } else return $avCaches;

    }


    private function cacheError($msg){//triggers error

        trigger_error('
wrapperCache error: '.$msg.

            '
If you want you can try with \'auto\' for auto select a compatible cache.

                   
Or choose a supported cache from list:'.$this->getAvailableCache(), E_USER_ERROR);

    }

}


声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn