Last active
August 29, 2015 14:04
-
-
Save zhoumengkang/5e4018096192b695ad14 to your computer and use it in GitHub Desktop.
练习:用mysql建一张表来模拟memcache做缓存操作类,要求用到工厂模式,单件模式,适配器模式
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
class Cache | |
{ | |
private static $instance = array(); | |
/** | |
* 缓存实例化的工厂方法并且确保单例 | |
*/ | |
public static function getInstance( $type,$options=array()){ | |
$type = strtolower(trim($type)); | |
if(isset(self::$instance[$type])){ | |
return self::$instance[$type]; | |
} | |
$class = 'Cache'.ucwords($type); | |
//class_exists 前提是已经有了自动载入机制 | |
if(class_exists($class)){ | |
$cache = new $class($options); | |
self::$instance[$type] = $cache; | |
}else{ | |
throw new Exception('error cache type'); | |
} | |
return $cache; | |
} | |
} | |
/** | |
* 封装适配器接口规范 | |
*/ | |
interface CacheInterface | |
{ | |
function set($name, $value, $expire = null); | |
function get($name); | |
function delete($name); | |
} | |
abstract class CacheAbstract implements CacheInterface | |
{ | |
//设置默认的 | |
public $options = array('prefix'=>'zmk_','expire'=>'60'); | |
} | |
class CacheApc extends CacheAbstract | |
{ | |
public function __construct($options=array()) { | |
if(!function_exists('apc_cache_info')) { | |
die('apc缓存扩展不存在'); | |
} | |
$this->options = array_merge($this->options,$options); | |
} | |
public function get($name) { | |
return apc_fetch($this->options['prefix'].$name); | |
} | |
public function set($name, $value, $expire = null) { | |
if(is_null($expire)) { | |
$expire = $this->options['expire']; | |
} | |
$name = $this->options['prefix'].$name; | |
return apc_store($name, $value, $expire); | |
} | |
public function delete($name) { | |
return apc_delete($this->options['prefix'].$name); | |
} | |
public function clear() { | |
return apc_clear_cache(); | |
} | |
} | |
$apc = Cache::getInstance('Cache',array('prefix'=>'zhoumengkang_')); | |
$apc->set('test','周梦康',60); | |
echo $apc->get('test'); | |
var_dump($apc->options); | |
class CacheMemcache extends CacheAbstract | |
{ | |
private $handler; | |
public function __construct($options=array()) { | |
if(!extension_loaded('memcache')){ | |
die('memcache扩展不存在'); | |
} | |
$this->options = array_merge($this->options,array('host'=>'localhost','port'=>'11211'),$options); | |
$this->handler = new Memcache; | |
$func = $options['persistent'] ? 'pconnect' : 'connect'; | |
if($options['timeout'] === false){ | |
$this->handler->$func($this->options['host'], $this->options['port']); | |
}else{ | |
$this->handler->$func($this->options['host'], $this->options['port'], $this->options['timeout']); | |
} | |
} | |
public function get($name) { | |
return $this->handler->get($this->options['prefix'].$name); | |
} | |
public function set($name, $value, $expire = null) { | |
if(is_null($expire)) { | |
$expire = $this->options['expire']; | |
} | |
return $this->handler->set($this->options['prefix'].$name, $value, $expire); | |
} | |
public function delete($name,$timeout = null) { | |
if(is_null($timeout)){ | |
return $this->handler->delete($this->options['prefix'].$name); | |
}else{ | |
return $this->handler->delete($this->options['prefix'].$name,$timeout); | |
} | |
} | |
public function clear() { | |
return $this->handler->flush(); | |
} | |
} | |
//$memcache = new CacheMemcache(array('prefix'=>'haha_','persistent'=>true,'timeout'=>false)); | |
$memcache = Cache::getInstance('memcache',array('prefix'=>'haha_','persistent'=>true,'timeout'=>false)); | |
$memcache->set('test2','周梦康康梦周',60); | |
echo $memcache->get('test2'); | |
class CacheMySQL extends CacheAbstract | |
{ | |
private $handler; | |
public function __construct($options=array()) { | |
if(!extension_loaded('pdo_mysql')){ | |
die('pdo_mysql扩展不存在'); | |
} | |
$this->options = array_merge($this->options,array('host'=>'localhost','port'=>'3306'),$options); | |
$this->handler = new PDO('mysql:host='.$this->options['host'].';port='.$this->options['port'].';dbname='.$this->options['database'], $this->options['user'], $this->options['password']); | |
$this->handler->query("set names utf8"); | |
} | |
public function get($name) { | |
$name = $this->options['prefix'].$name; | |
$sql = "SELECT `cache_value` FROM `{$this->options['tablename']}` WHERE `cache_key` = '{$name}'"; | |
$res = $this->handler->query($sql); | |
foreach ($res as $row) { | |
return $row['cache_value']; | |
} | |
} | |
public function set($name, $value, $expire = null) { | |
if(is_null($expire)) { | |
$expire = $this->options['expire']; | |
} | |
$name = $this->options['prefix'].$name; | |
$time = time(); | |
$expire = $expire + time();//假设定时任务每秒请求执行一次autoDeleteCachePerSecond() | |
if($this->handler->query("SELECT * FROM `{$this->options['tablename']}` WHERE `cache_key` = '{$name}'")){ | |
$sql = "UPDATE `{$this->options['tablename']}` SET `cache_value` = '{$value}',`update_time` = {$time} ,`cache_time` = {$expire}"; | |
}else{ | |
$sql = "INSERT INTO `{$this->options['tablename']}` (`cache_key`,`cache_value`,`create_time`,`cache_time`) VALUES('{$name}','{$value}',{$time},{$expire})"; | |
} | |
return $this->handler->exec($sql); | |
} | |
/** | |
* 每秒自动全表扫描删除该存活期等于该时间戳下的所有缓存数据 | |
*/ | |
public function autoDeleteCachePerSecond() { | |
$sql = "DELETE FROM `{$this->options['tablename']}` WHERE `cache_time` = ".time(); | |
$this->handler->exec($sql); | |
} | |
public function delete($name) { | |
$sql = "DELETE FROM `{$this->options['tablename']}` WHERE `cache_key` = '".$this->options['prefix'].$name."'"; | |
$this->handler->exec($sql); | |
} | |
public function clear() { | |
$sql = "DELETE FROM `{$this->options['tablename']}`"; | |
$this->handler->exec($sql); | |
} | |
} | |
//$mysqlCache = new CacheMySQL(array('database'=>'design_patterns','tablename'=>'mysql_cache_demo','user'=>'root','password'=>'zmkzmk')); | |
$mysqlCache = Cache::getInstance('Mysql',array('database'=>'design_patterns','tablename'=>'mysql_cache_demo','user'=>'root','password'=>'zmkzmk')); | |
$mysqlCache->set('mengkang','php_mysql_cache_test'); | |
echo $mysqlCache->get('mengkang'); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment