代码改变世界

php

2013-01-09 17:34  cczw  阅读(357)  评论(0)    收藏  举报
<?php

define('APPPATH',dirname(__FILE__)); 

$config=array();
$config['cache']=array(
	'memcache' =>array(
		'servers'=>array(
			'memcache1'=>array('host'=>'127.0.0.1','port'=>11211,'weight'=>25),
		),
 		'ttl'=>60*24, //一个小时,0代表永不过期
	),
	'file' =>array(
		//'mode' =>1,			//1 按key存文件,2 按天存文件,3按小时存文件
		'path' =>APPPATH.'/cache',
		'ext'  =>'.cache',
		'ttl'=>60*24, //一个小时,0代表永不过期
	),
);

interface Cache{
    public function get($key);
    public function set($key,$val,$ttl);
    public function delete($key,$ttl=0);
    public function clean();
}
class Cache_memcache implements Cache{
	private $default_config=array('host'=>'127.0.0.1','port'=>11211,'weight'=>1);
	private static $memcache;
	private $ttl=0;
	function __construct($config=array()){
		if (!isset(self::$memcache)) {
			self::$memcache = new Memcache;
		}
		if (isset($config['ttl'])) {
			$this->ttl=$config['ttl'];
		}
		//如果由配置信息,则根据配置信息初始化,否则加载默认配置
		if (isset($config['servers']) && is_array($config['servers'])) {
			foreach ($config['servers'] as $server) { 
				self::$memcache->addServer($server['host'],$server['port'],TRUE,$server['weight']);
			}
		}else{
			self::$memcache->addServer($this->default_config['host'],$this->default_config['port'],TRUE,$this->default_config['weight']);
		}
	}
    public function get($key){
        if (isset(self::$memcache)) {
        	return self::$memcache->get($key);
        }else{
        	return FALSE;
        }
    }
    public function set($key,$val,$ttl=-1){
 		if (isset(self::$memcache)) {
 			if ($ttl<0) {
 				$ttl=$this->ttl;
			}
        	return self::$memcache->set($key, $val, 0, $ttl);
        }else{
        	return FALSE;
        }
    }
    public function delete($key,$ttl=0){
 		if (isset(self::$memcache)) {
        	return self::$memcache->delete($key,$ttl);
        }else{
        	return FALSE;
        }
    }
    public function clean(){
    	if (isset(self::$memcache)) {
        	return self::$memcache->flush();
        }else{
        	return FALSE;
        }
    }
}

class Cache_file implements Cache{
	private static $path;
	private $def_path='./cache';
	private $ttl=0;
	private $ext='.cache';
	function __construct($config=array()){
		if (isset($config['ttl'])) {
			$this->ttl=$config['ttl'];
		}
		if(isset($config['path'])) {
			$path=rtrim($config['path'],DIRECTORY_SEPARATOR);
			$this->def_path=self::$path=$path;
		}else{
			self::$path=$this->def_path;
		}
		if(!file_exists(self::$path)){
			$this->_mkdirs(self::$path);
		}
	}
	//在主缓存路径下设置缓存文件夹
	// "./",".",""都表示初始缓存目录
	public function setPath($dirname){
		$dirname=trim($dirname,DIRECTORY_SEPARATOR);
		$path=$this->def_path.'/'.$dirname;
		try {
			if (!file_exists($path)) {
				$this->_mkdirs($path);
			}
			self::$path=$path;
			return TRUE;
		} catch (Exception $e) {
			return FALSE;
		}
	}

	public function _mkdirs($path, $mode = 0777)
	{	
		if (is_dir($path) || @mkdir($path, $mode)) return TRUE;
		if (!$this->_mkdirs(dirname($path), $mode)) return FALSE;
		return @mkdir($path, $mode);
    }

    public function _cleanDir($path,$rmdir=FALSE){
    	if (!$dir = @opendir($path)){
			return FALSE;
		}
		while (FALSE!==($item=readdir($dir))) {
			if (in_array($item, array('.','..'))) {
				continue;
			}
			$f=$path.DIRECTORY_SEPARATOR.$item;
 			if (is_dir($f)) {
				 $this->_cleanDir($f,TRUE);
			}else{
				unlink($f);
			}
		}
		closedir($dir);
		if ($rmdir) {
			return rmdir($path);
		}
    }
	public function get($key){
		$fname=$this->_get_fname($key);
		if (file_exists($fname)) {
			$data=file_get_contents($fname);
			$data=unserialize($data);
 			//判断过期
			if (is_array($data)) {
				if ($data['ttl']==0 || time()-$data['stime']<$data['ttl']) {
					return $data['data'];
				}
			}
			@unlink($this->_get_fname($key));
		}
		return FALSE;
	}
    public function set($key,$val,$ttl=-1){
		if ($ttl<0) {
			$ttl=$this->ttl;
		}
		$path=$this->_get_fname($key);
		if (!@$fp = fopen($path,'w+'))
		{
			return FALSE;
		}
		//组合数据
		$data=array(
			'ttl'=>$ttl,
			'stime'=>time(),
			'data'=>$val,
		);
		$data=serialize($data);
		try {
			flock($fp, LOCK_EX);
			fwrite($fp, $data);
			flock($fp, LOCK_UN);
			fclose($fp);
			//file_put_contents($path, $data,LOCK_EX);
			@chmod($path, 0777);
			return TRUE;
		} catch (Exception $e) {
			return FALSE;
		}
    }
    public function delete($key,$ttl=0){
    	return unlink($this->_get_fname($key));
    }
    public function clean(){
    	return $this->_cleanDir($this->def_path);
    }

    private function _get_fname($key){
    	return self::$path.'/'.$key.$this->ext;
    }
}


class Drive{
    public $config;

    protected $drive_type;	//驱动类型  lower
    protected $lib_class;
    protected static $driver_list=array('cache');	//支持的驱动接口列表

    function __construct($config=array()){
    	$this->config=$config;
    }
    //链式获取驱动实例
    function __get($child){
        //第一层驱动接口
        if (in_array($child, self::$driver_list)) {
            $lib_name=ucfirst($child);
            if(interface_exists($lib_name)){
                $this->drive_type=$child;
                return $this;
            }
            return FALSE;
        }else{
            //第二层判断实例是否存在,否则创建
            $drive_class=ucfirst($this->drive_type);
            $lib_name=$drive_class.'_'.$child;
            $this->lib_class=$child;
            if (isset(self::$driver_list[$this->drive_type][$child])) {
            	return $this;
            }else{
            	if(class_exists($lib_name) && in_array($drive_class, class_implements($lib_name)) ) {
            		$refClass= new ReflectionClass($lib_name);
            		$instance=$refClass->newInstance($this->config[$this->drive_type]);
            		self::$driver_list[$this->drive_type][$child]=array(
            			'refClass'=>$refClass,
            			'instance'=>$instance,
            		);
 	                return $this;
	            }
            }
            return FALSE;
        }
    }
    function __call($method,$args=array()){
    	if (isset($this->drive_type)) {
    		$drivesc=self::$driver_list[$this->drive_type];
    		if(isset($drivesc[$this->lib_class]) && $drivesc[$this->lib_class]['refClass']->hasMethod($method)){
    			return call_user_func_array(array($drivesc[$this->lib_class]['instance'],$method), $args);
    		}
    	}
    	return FALSE;
    }
}

//运行实例
//driver->驱动接口->驱动类->方法 
$drive=new Drive($config);
$drive->cache->memcache->set('ok','1000',1);
$val=$drive->cache->memcache->get("ok1");
////////////
$drive->cache->file->set('ok',array('a'=>100));
$drive->cache->file->setPath('a/b');
$drive->cache->file->set('ok',array('a'=>111));
$val=$drive->cache->file->get('ok');
var_dump($val);
$drive->cache->file->setPath('.');  
$val=$drive->cache->file->get('ok');
var_dump($val);
//$drive->cache->file->clean();
////////////////