`
hudeyong926
  • 浏览: 2028282 次
  • 来自: 武汉
社区版块
存档分类
最新评论

PHP比较全面的缓存类

阅读更多
<?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);
    }
}
 wrapperCache基于文件的缓存处理类
<?php
/*
* Name:    fileCache
fileCache::getInstance(3600,'E:\www\cache\\')->cache('key','value');
* Notes:   fileCache class, caches variables in standalone files if value is too long or uses unique file for small ones
*/

class fileCache {
	private $cache_path;//path for the cache
	private $cache_expire;//seconds that the cache expires
	private $application=array();//application object like in ASP
	private $application_file;//file for the application object
	private $application_write=false;//if application write is true means there was changes and we need to write the app file
	private $debug=false; //no debug by default
	private $log=array();//log for the debug system
	private $start_time=0;//application start time
	private static $content_size=64;//this is the max size can be used in APP cache if bigger writes independent file
	private static $instance;//Instance of this class

	// Always returns only one instance
	public static function getInstance($exp_time=3600,$path='cache/'){
		if (!isset(self::$instance)){//doesn't exists the isntance
			self::$instance = new self($exp_time,$path);//goes to the constructor
		}
		return self::$instance;
	}

	//cache constructor, optional expiring time and cache path
	private function __construct($exp_time,$path){
		$this->start_time=microtime(true);//time starts
		$this->cache_expire=$exp_time;
		if ( ! is_writable($path) ) trigger_error('Path not writable:'.$path);
		else $this->cache_path=$path;
		$this->APP_start();//starting application cache
	}

	public function __destruct() {
		$this->addLog('destruct');
		$this->APP_write();//on destruct we write if needed
		$this->returnDebug();
	}

	// Prevent users to clone the instance
	public function __clone(){
		trigger_error('Clone is not allowed.', E_USER_ERROR);
	}

	//deletes cache from folder
	public function deleteCache($older_than=''){
		$this->addLog('delete cache');
		if (!is_numeric($older_than)) $older_than=0;
		$files = scandir($this->cache_path);
		foreach($files as $file){
			if (strlen($file)>2 && time() > (filemtime($this->cache_path.$file) + $older_than) ) {
				unlink($this->cache_path.$file);//echo "<br />-".$file;
				$this->addLog('delete cache file:'.$this->cache_path.$file);
			}
		}

	}

	//writes or reads the cache
	public function cache($key, $value=''){		
		if ($value!=''){//wants to write
			if (strlen(serialize($value)) > 64 ){//write independent file it's a big result
				$this->addLog('cache function write in file key:'. $key);
				$this->put($key, $value);
			}else{
				$this->addLog('cache function write in APP key:'. $key);
				$this->APP($key,$value);//write in the APP cache
			}
		}else{//reading value
			if ( $this->APP($key)!=null ){
				$this->addLog('cache function read APP key:'. $key);
				return $this->APP($key);//returns from app cache
			}else{
				$this->addLog('cache function read file key:'. $key);
				return $this->get($key);//returns from file cache
			}
		}
	}

	//deletes a key from cache
	public function delete($name){
		if ( $this->APP($name)!=null ){//unset the APP var
			$this->addLog('unset APP key:'. $name);
			unset($this->application[md5($name)]);
			$this->application_write=true;//says that we have changes to later save the APP
		}elseif ( file_exists($this->fileName($name)) ){//unlink filename
			$this->addLog('unset File key:'. $name);
			unlink($this->fileName($name));
		}
	}

	// Overloading for the variables and automatically cached
	public function __set($name, $value) {
		$this->cache($name, $value);
	}

	public function __get($name) {
		return $this->cache($name);
	}

	public function __isset($name) {//echo "Is '$name' set?\n"
		$this->addLog('isset key:'. $name);
		$value=$this->cache($name);
		return isset($value);
	}

	public function __unset($name) {//echo "Unsetting '$name'\n";
		$this->delete($name);
	}
	//end overloads

	//////////Cache for files individually///////////////////

	//creates new cache files with the given data, $key== name of the cache, data the info/values to store
	private function put($key, $data){
		if ( $this->get($key)!= $data ){//only write if it's different
			$values = serialize($data);
			$filename = $this->fileName($key);
			$file = fopen($filename, 'w');
			if ($file){//able to create the file
				$this->addLog('writting key: '.$key.' file: '.$filename);
				fwrite($file, $values);
				fclose($file);
			}
			else  $this->addLog('unable to write key: '.$key.' file: '.$filename);
		}//end if different
	}

	//returns cache for the given key
	private function get($key){
		$filename = $this->fileName($key);
		if (!file_exists($filename) || !is_readable($filename)){//can't read the cache
			$this->addLog('can\'t read key: '.$key.' file: '.$filename);
			return null;
		}

		if ( time() < (filemtime($filename) + $this->cache_expire) ) {//cache for the key not expired
			$file = fopen($filename, 'r');// read data file
			if ($file){//able to open the file
				$data = fread($file, filesize($filename));
				fclose($file);
				$this->addLog('reading key: '.$key.' file: '.$filename);
				return unserialize($data);//return the values
			}else{
				$this->addLog('unable to read key: '.$key.' file: '.$filename);
				return null;
			}
		}else{
			$this->addLog('expired key: '.$key.' file: '.$filename);
			unlink($filename);
			return null;//was expired you need to create new
		}
	}

	//returns the filename for the cache
	private function fileName($key){
		return $this->cache_path.md5($key);
	}
	//////////END Cache for files individually///////////////////

	//////////Cache for APP variables///////////////////

	//load variables from the file
	private function APP_start ($app_file='application'){
		$this->application_file=$app_file;

		if (file_exists($this->cache_path.$this->application_file)){ // if data file exists, load the cached variables
			//erase the cache every X minutes
			$app_time=filemtime($this->cache_path.$this->application_file)+$this->cache_expire;
			if (time()>$app_time){
				$this->addLog('deleting APP file: '.$this->cache_path.$this->application_file);
				unlink ($this->cache_path.$this->application_file);//erase the cache
			}else{//not expired
				$filesize=filesize($this->cache_path.$this->application_file);
				if ($filesize>0){
					$file = fopen($this->cache_path.$this->application_file, 'r');// read data file
					if ($file){
						$this->addLog('reading APP file: '.$this->cache_path.$this->application_file);
						$data = fread($file, $filesize);
						fclose($file);
						$this->application = unserialize($data);// build application variables from data file
					}//en if file could open
				}//end if file size

			}
		}else{//if the file does not exist we create it
			$this->addLog('creating APP file: '.$this->cache_path.$this->application_file);
			fopen($this->cache_path.$this->application_file, 'w');
		}

	}

	// write application data to file
	private function APP_write(){
		if ($this->application_write){
			$data = serialize($this->application);
			$file = fopen($this->cache_path.$this->application_file, 'w');
			if ($file){
				$this->addLog('writting APP file: '.$this->cache_path.$this->application_file);
				fwrite($file, $data);
				fclose($file);
			}
		}
	}

	//returns the value form APP cache or stores it
	private function APP($var,$value=''){
		if ($value!=''){//wants to write
			if (is_array($this->application)){
				if ( array_key_exists(md5($var), $this->application) ){//exist the value in the APP
					$write=false;//we don't need to wirte
					if ($this->application[md5($var)]!=$value)$write=true;//but exists and is different then we write
				}
				else $write=true;//not set we write!
			}
			else $write=false;

			if ($write){
				$this->addLog('writting APP key:'.$var);
				$this->application[md5($var)]=$value;
				$this->application_write=true;//says that we have changes to later save the APP
			}
		}else{//reading
			if ( !is_array($this->application) || ! array_key_exists(md5($var), $this->application) ){
				$this->addLog('nothing found for APP key:'.$var);
				return null;//nothing found not in array
			}else{
				$this->addLog('reading APP key:'.$var);
				return $this->application[md5($var)];//return value
			}
		}
	}
	//////////End Cache for APP variables///////////////////

	////DEBUG
	//sets debug on or off
	public function setDebug($state){
		$this->debug=(bool) $state;
	}

	public function returnDebug($type='HTML'){
		if ($this->debug){
			switch($type){
				case 'array':
					return $this->log;
					break;
				case 'HTML'://returns debug as HTML
				echo '<ol>';
				foreach($this->log as $key=>$value){//loop in the log var
					echo '<li>'.$value.'</li>';
				}
				echo '</ol>';
				break;
			}
		}
		else return false;
	}

	//add debug log
	public function addLog($value){
		if ($this->debug){//only if debug enabled
			array_push($this->log, round((microtime(true) - $this->start_time),5).'s - '. $value);
		}
	}
}
?> 
分享到:
评论

相关推荐

    比较全面的一个php缓存类.zip

    一般来说,缓存的目的是把数据放在一个地方让访问的更快点,毫无疑问,内存是最快的,但是,几百M的数据能往内存放么?这不现实,当然,有的时候临时放如服务器缓存,如ob_start()这个缓存页面开启的话在发送文件头之前页面...

    一个实用的PHP缓存类.zip

    总的来说,这个PHP缓存类提供了基础但全面的缓存管理功能,适合作为项目中缓存策略的基石。通过合理地运用缓存技术,开发者可以提升网站的性能,改善用户体验,同时减轻服务器的压力。在使用过程中,还需要注意缓存...

    简单的php缓存类分享 php缓存机制

    在本文中,我们将探讨一个简单的PHP缓存类的实现机制,这是程序员在处理Web应用程序时经常使用的一种技术,旨在优化性能和响应时间。通过介绍一个自定义的PHP缓存类,我们将了解如何利用文件系统存储临时数据,并...

    计算机后端-全面解读PHP面试-案类考察点数据库缓存层的优化.wmv

    计算机后端-全面解读PHP面试-案类考察点数据库缓存层的优化.wmv

    SK百度知道小偷伪静态缓存极速版php版v2.0

    【标题】"SK百度知道小偷伪静态缓存极速版php版v2.0"是一个基于PHP编程语言的网络爬虫程序,专用于抓取和显示百度知道平台上的问答内容。该程序的版本号为v2.0,意味着它经过了一次重大更新,主要针对百度知道的规则...

    简单实用的网站PHP缓存类实例

    5. 缓存文件的管理:实例中的缓存类提供了对缓存文件的全面管理,包括创建、读取、更新和删除(CRUD)缓存文件。同时,类内部会自动处理缓存文件的存储路径和文件名,使开发者无需关心这些细节。 6. 文件操作函数...

    XDO是一个PHP数据类它包括了数据库缓存和上传

    总结起来,XDO是一个全面的数据处理工具,为PHP开发者提供了数据库操作、缓存管理和文件上传的便利。它的易用性、灵活性和兼容性使得在各种PHP项目中都能发挥重要作用,提升了开发效率和应用性能。

    缓存全面剖析.pdf及安装文件、缓存客户端、源码

    本资料包主要涵盖了关于缓存的全面剖析,特别是针对Memcached这一流行缓存系统的知识。让我们逐一探讨这些内容。 首先,"缓存全面剖析.pdf"很可能是一份详尽的缓存技术指南,它可能包含以下知识点: 1. **缓存的...

    php中文参考手册 超级全面

    性能优化方面,可以使用opcode缓存如APC、OPcache,减少脚本解析时间,提高运行速度。 这份《PHP中文参考手册》是PHP开发者的重要工具,它详细介绍了PHP的各项功能和使用技巧,无论是初学者还是经验丰富的开发者,...

    功能强大的php图片缩略图类

    6. **缓存机制**:为了提高性能,`timthumb.php` 可能会将生成的缩略图保存在服务器上,当再次请求相同的缩略图时,直接从缓存中读取,而不是每次都重新生成。 7. **跨域支持**:对于分布式系统或者CDN环境,`...

    PHP专题——重点函数_静态化_缓存_面向对象_异常处理

    综上所述,PHP专题涵盖了从基础到高级的关键知识点,包括重要函数的选择性解析、面向对象编程的深入理解、异常处理的应用以及静态化和缓存技术,旨在帮助开发者全面掌握PHP的核心技能,以适应不断发展的Web开发需求...

    php连接mysql数据库操作类

    这款PHP MySQL操作类提供了全面的功能,涵盖了数据的查询、更新、删除等操作,适用于初学者进行学习和实践,同时也为有经验的开发者提供了一个可自定义的基础框架。下面我们将详细讨论其中涉及的关键知识点。 1. **...

    php实现网页缓存的工具类分享

    文章中首先提到的是缓存类的定义,包括缓存文件存放目录($dir)、缓存文件有效期($lifetime)、缓存文件路径($cacheid)、缓存文件扩展名($ext)四个私有成员变量。这些变量共同定义了缓存的工作环境和行为特性。 缓存...

    php5权威指南

    《PHP5权威指南》是一本全面深入探讨PHP5编程技术的专业书籍,旨在为读者提供一个系统、详尽的PHP5学习资源。这本书涵盖了从基础语法到高级特性的广泛内容,对于初学者和经验丰富的开发者来说,都是宝贵的参考资料。...

    史上最强大的php分页类

    总结来说,“史上最强大的PHP分页类”应该是功能全面、易用且高度可定制的工具,它简化了开发者处理分页逻辑的复杂性,提高了代码的可读性和项目的可维护性。通过对上述关键知识点的理解和实践,开发者可以构建出...

    php codephp codephp code

    **面向对象编程**:PHP5引入了全面的面向对象支持,包括类、对象、继承、封装和多态。这使得大型项目可以组织得更有序。 **PHP框架**:如Laravel、Symfony、CodeIgniter等PHP框架,提供了MVC(模型-视图-控制器)...

    PHP笔试题D库

    总的来说,【PHP笔试题D库】提供了全面的复习材料,涵盖了从基础到高级的PHP知识,对于希望在PHP领域获得理想职位的开发者来说,这份资源无疑是一份宝贵的参考资料。通过深入学习和实践这些题目,你可以更好地应对...

    win_php_memcache.dll集合

    《全面解析PHP与Memcache扩展:从5.3到7.1的32位与64位支持》 PHP作为一款流行的服务器端脚本语言,广泛应用于Web开发领域。在处理大量数据时,高效的缓存机制是必不可少的,而Memcache就是这样的一个内存对象缓存...

Global site tag (gtag.js) - Google Analytics