Skip to content

Instantly share code, notes, and snippets.

@zhoumengkang
Last active August 29, 2015 14:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zhoumengkang/5e4018096192b695ad14 to your computer and use it in GitHub Desktop.
Save zhoumengkang/5e4018096192b695ad14 to your computer and use it in GitHub Desktop.
练习:用mysql建一张表来模拟memcache做缓存操作类,要求用到工厂模式,单件模式,适配器模式
<?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