memcache系列---缓存代理类的实现(二)
来源:互联网 发布:linux 添加yum源 编辑:程序博客网 时间:2024/05/19 19:40
在项目中可能会使用到多种缓存技术,如memcache,redis,文件缓存等。如果能把这些缓存机制统一接口,对外开放,让使用者可以不用关心缓存的内部实现就可以随意调用这些缓存类。
比如我要使用memcache把key=>value保存在static_zh这台memcache服务器上。我期望的实现方式是: F('Memcache')->static_zh->set('key', 'value'); 也就是说,我不用操心memcache内部到底是如何处理我的请求的,我只需要一个memcache接口就可以了。同理,当我想获取到redis服务器上message库里面的$cacheKey的缓存值,我期望的做法是 F('Redis')>message->get($cacheKey);
实现这样的做法,需要一个缓存代理类,来完全代理缓存的操作,用户只需要使用这个代理类就可以进行各种缓存操作。
核心问题
(1)一个代理类可以代理多种缓存类(memcache,redis file)
( 2 ) 每次代理的类缓存类可以有多个。这句话的意思是,在一次请求中,可能需要使用到多种缓存类。比如某一次请求既需要实例化memcache类,需要实例化redis类,那么,这个代理类是否可以使用单例模式来实现。
(3)这个代理类可以访问到被代理类的方法。(不然代理就无从说起)
(4)这个代理类在什么时候会实例化被代理的类。这是我们比较关心的问题。一般想法是:在使用F('Memcache')的时候,就代理内部就实例化memcache类。这样其实是错的,因为实例化memcache的时候,需要读入memcache的配置文件,我需要知道我到底实例化那个配置文件的memcache。所以,必须是读入相应的配置文件的时候,才是实例化一个被代理类的时候。这里巧妙的使用了__get()和__call()两个PHP魔术方法来实现。
实现架构图
实现代码
<?php/** * 缓存经理人 * * @author JiangJian <silverd@sohu.com> * $Id: Cache.php 142 2012-11-28 01:42:39Z jiangjian $ */class Com_Cache{ /** * 使用的缓存类名 * * @var string */ private $_className; /** * 默认模块 * * @var string */ private $_defaultModule = 'default'; /** * 单例模式 * * @var array */ private static $_instances = array(); public static function getInstance($className = 'Memcache') { if (! isset(self::$_instances[$className])) { self::$_instances[$className] = new self($className); } return self::$_instances[$className]; } private function __construct($className) { $this->_className = 'Com_Cache_' . $className; } /** * 每个模块都有一个缓存实例 * * @param string $module * @return object Com_Cache_* */ public function __get($module) { return $this->{$module} = new $this->_className($module); } /** * 默认模块的魔术方法(那么调用时可以省略默认模块名) * 例如:$this->get('key') 等价于 $this->default->get('key') * * @param string $method * @param array $args * @return mixed */ public function __call($method, $args) { // 注意代码的执行逻辑: $this->_defaultModule为default,即$cacheObj = $this->default // 但是这个类有不存在default这个属性,这时就会执行__get($module),从而实例化某个类并返回 $cacheObj = $this->{$this->_defaultModule}; return call_user_func_array(array($cacheObj, $method), $args); }}
组件方法的实现代码:
/** * 常用组件工厂 * * @param string $component * @return object */function F($component){ if (! isset($GLOBALS['__G_' . $component])) { switch ($component) { case 'Memcache': $GLOBALS['__G_Memcache'] = Com_Cache::getInstance('Memcache'); break; case 'Redis': $GLOBALS['__G_Redis'] = Com_Cache::getInstance('Redis'); break; } } return $GLOBALS['__G_' . $component];}
调用方法
- memcache系列---缓存代理类的实现(二)
- Discuz!的Memcache缓存实现
- Discuz!的Memcache缓存实现
- Discuz!的Memcache缓存实现
- Discuz!的Memcache缓存实现
- Discuz!的Memcache缓存实现
- Discuz!的Memcache缓存实现
- Discuz!的Memcache缓存实现
- DISCUZ!的MEMCACHE缓存实现
- Discuz!的Memcache缓存实现
- Discuz!的Memcache缓存实现
- memcache系列--处理缓存的三种方案(三)
- memcache系列——memcache客户端类的实现(一)
- Memcache学习笔记二:Memcache做Mybatis的缓存
- Memcache(MC)系列(二)Linux下Memcache安装
- Memcache系列(二)PHP安装memcache扩展
- Redis系列(二)--缓存设计(整表缓存以及排行榜缓存方案实现)
- 基于memcache的远程缓存工具类
- 动态规划问题详解(二)
- jQuery AJAX实现调用页面后台方法
- mysql5.6编码问题设置
- Hive的原理—— 深入浅出学Hive
- 数位dp简单题目汇总
- memcache系列---缓存代理类的实现(二)
- 基于Android的无线视频监控的设计与实现 -- 开题报告
- Mssql未能加载文件或程序集“Microsoft.SqlServer.Sqm, 未能加载文件或程序集“Microsoft.SqlServer.Sqm, Version=10.0.0.0, Cultu
- Jsonp实现跨域请求数据
- CentOS 6 下升级安装Mysql 5.5 完整步骤
- DDR内存 时序指南
- Spring+Servlet
- 战舰板stm32的adc dma实验
- NoSQL之Redis对set(集合)数据类型的操作之二