欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  后端开发

PHP比较全面的缓存类

程序员文章站 2022-04-19 13:46:54
...
<?php

/*

* 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 <b>'.$type.'</b>';

$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 = '<ul>';

foreach ($avCaches as $c) {

$ret .= '<li>' . $c[0] . ' - ';

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

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

$ret .= '</ll>';

}

return $ret . '</ul>';

} else return $avCaches;

}


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

trigger_error('<br /><b>wrapperCache error</b>: '.$msg.

'<br />If you want you can try with \'auto\' for auto select a compatible cache.

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

}

}