`
faiinlove
  • 浏览: 57796 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

实用PHP技巧:万能Cache

    博客分类:
  • php
阅读更多

Web程序员最常使用的数据库封装方式就是DAO,其实和马丁大爷在PoEAA中所说的表数据入口差不多:

01 class ArticleDAO
02 {
03     public function findById($id)
04     {
05         // SELECT * FROM article WHERE id = ...
06     }
07
08     public function findByTitle($title)
09     {
10         // SELECT * FROM article WHERE title LIKE ...
11     }
12 }
 

如上所示,是一个最简单的DAO例子,为了提高效率,很多时候需要把查询结果都缓存起来:

01 class ArticleCache
02 {
03     protected $cache;
04     protected $dao;
05
06     public function __construct($cache, $dao)
07     {
08         $this->cache = $cache;
09         $this->dao = $dao;
10     }
11
12     public function findById($id)
13     {
14         $key = 'id_' . $id;
15         if (!($result = $this->cache->get($key))) {
16             $result = $this->cache->findById($id);
17             $this->cache->set($key, $result);
18         }
19         return $result;
20     }
21
22     public function findByTitle($title)
23     {
24         $key = 'title_' . $title;
25         if (!($result = $this->cache->get($key))) {
26             $result = $this->cache->findByTitle($title);
27             $this->cache->set($key, $result);
28         }
29         return $result;
30     }
31 }
32
33 $memcache = new Memcache();
34 $memcache->connect('host', 'port');
35
36 $dao = new ArticleDAO();
37
38 $cache = new ArticleCache($memcache, $dao);
39
40 $cache->findById('id');
41 $cache->findByTitle('title');
 

解决问题时,面向对象编程不变的伎俩就是引入新层,上面这个缓存功能的实现亦是如此,阿基米德当年叫嚷着:给我一个支点,我可以撬动地球;面向对象的粉丝们也常有如此的豪言:加入一个新层,就可以实现任何功能。不过这里面出现了重复的坏味道,findById和findByTitle两个方法的实现代码大体上是重复的,继续重构:

01 class Cache
02 {
03     protected $cache;
04     protected $dao;
05
06     public function __construct($cache, $dao)
07     {
08         $this->cache = $cache;
09         $this->dao = $dao;
10     }
11
12     public function __call($name, $arguments)
13     {
14         if (strtolower(substr($name, 0, 4)) != 'find') {
15             return false;
16         }
17
18         $key = md5(strtolower(get_class($this->dao) . $name . serialize($arguments)));
19         if (!($result = $this->cache->get($key, $flags))) {
20             $result = call_user_func_array(array($this->dao, $name), $arguments);
21             $this->cache->set($key, $result);
22         }
23         return $result;
24     }
25 }
26
27 $memcache = new Memcache();
28 $memcache->connect('host', 'port');
29
30 $dao = new ArticleDAO();
31
32 $cache = new Cache($memcache, $dao);
33
34 $cache->findById('id');
35 $cache->findByTitle('title');
 

通过使用魔术方法__call,我们成功的去除了重复代码,而且这个Cache可以说是“万能”的,因为除了ArticleDAO外,我们可能还有CategoryDAO,CommentDAO等等,都可以用这个Cache来实现缓存。当然,Cache本身还不完善,有很多提升的余地,比如说缓存时间的设置,或者内容更新时如何通过观察者模式的方式来完成缓存的主动更新等等,这些问题我就不得瑟了,留给读者自己思考。

分享到:
评论

相关推荐

    实验五: 虚拟Cache与伪相联Cache

    2. **实现两路伪相联Cache:**根据指定配置,在模拟器上实现伪相联Cache,即每组有两个槽。 3. **比较不同Cache配置的性能:** - 运行一段程序,记录在伪相联Cache配置下的缓存失效情况。 - 将结果与直接映射Cache...

    cache-api-1.1.1-API文档-中文版.zip

    Maven坐标:javax.cache:cache-api:1.1.1; 标签:javax、cache、api、中文文档、jar包、java; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码和...

    等待事件row cache lock,latch row cache objects处理过程.txt

    等待事件row cache lock,latch row cache objects处理过程

    计算机组成原理:4.4CACHE.ppt

    计算机组成原理:4.4CACHE.ppt

    Zend Cache:一个实用的缓存php类库.zip

    "Zend Cache:一个实用的缓存php类库.zip" 指的是一个基于PHP的缓存解决方案, Zend Cache,它被封装在一个压缩包文件中,供开发者下载使用。 **描述分析:** 描述简单明了,强调了 Zend Cache 是一个适用于PHP...

    CGI::Cache-开源

    CGI::Cache是一个基于Perl的开源模块,专为提高CGI(Common Gateway Interface)脚本的性能而设计。CGI是Web服务器与外部程序交互的一种标准方法,常用于执行动态内容生成,例如处理表单数据、数据库查询等。然而,...

    Zend Cache:一个实用的缓存php类库

    $cache = Zend_Cache::factory('Core', 'File', $frontendOptions, $backendOptions); // 存储数据 $data = array('key' => 'value'); $cacheId = 'my_cache_id'; $cache->save($data, $cacheId); // 检索数据 $...

    File::Cache-开源

    File::Cache 是一个 perl 模块,它允许通过文件系统跨进程共享对象数据。 现在不鼓励使用 File::Cache,而是支持 http://sourceforge.net/projects/perl-cache/ 上的新 Cache::Cache 项目。

    第5关:直接相联cache设计.txt

    直接相联cache是最简单的一种cache组织形式,其中每个主内存块只能映射到cache中的一个特定位置。 **特点**: - 每个主内存块只能映射到cache的一个固定位置。 - 如果新的内存块要替换掉已存在的块时,将直接覆盖该...

    CacheTool:一个清除APC/opcode缓存的类库

    `CacheTool` 是一款实用的类库,专门用于管理和清理APC和Opcode缓存。 **CacheTool功能详解** 1. **APC缓存管理**: - 清除APC数据:`CacheTool` 提供了命令行工具,可以快速清除APC中的用户、数据和文件缓存,...

    Lab #8: Cache

    【标题】:“Lab #8: Cache” 在计算机科学领域,Cache是硬件层面的关键技术,用于提升数据存取速度。此实验“Lab #8: Cache”旨在深入理解和掌握Cache的工作原理及其对系统性能的影响。在本实验中,我们将探索...

    oracle Library cache latch 竞争的解决

    ### Oracle Library Cache Latch 竞争的解决 在Oracle数据库中,`Library Cache Latch`竞争是一个常见的性能瓶颈问题,通常会导致系统响应时间增加、性能下降等问题。本篇文章将详细探讨如何诊断并解决该问题。 ##...

    透过专利看微处理器的技术发展(六)——Cache专利技术的发展历程.pdf

    Cache 技术发展历程概述 Cache 技术是微处理器技术发展的重要组成部分,Cache 技术的发展历程是理解微处理器技术发展的关键。通过对 Cache 技术的专利研究,我们可以揭示 Cache 技术的起源、发展历程和演进过程。 ...

    ZendCache一个通用的PHP缓存系统

    **标题解析:** "ZendCache一个通用的PHP缓存系统" ZendCache是PHP开发中广泛使用的缓存解决方案,它提供了一种高效的方式来存储和检索数据,以提高Web应用程序的性能。"通用"这个词表明该系统适用于多种场景和...

    shiro-cache-1.4.0-API文档-中英对照版.zip

    Maven坐标:org.apache.shiro:shiro-cache:1.4.0; 标签:apache、shiro、cache、中英对照文档、jar包、java; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,...

    Doctrine Cache:一个使用的php缓存类库.zip

    Doctrine Cache是PHP开发中的一个强大工具,它提供了一组统一的接口来管理和实现各种缓存策略。这个开源库使得在PHP项目中集成缓存功能变得简单且灵活,适用于那些需要提升性能、减少数据库负载的应用。在本文中,...

    第6关:4路组相连cache设计.txt

    在不同的Cache设计中,4路组相连Cache是一种折衷方案,在直接映射(Direct Mapped Cache)和全相联(Fully Associative Cache)之间取得平衡。 #### 基本概念 - **直接映射**:每个主内存块只能映射到Cache的一个...

    Chrome 进阶技巧:将缓存路径放到非系统分区并设置大小

    ### Chrome 进阶技巧:将缓存路径放到非系统分区并设置大小 #### 背景与需求 在日常使用过程中,很多用户发现Chrome浏览器默认会将安装程序、缓存及用户数据等存储在系统分区中。对于那些系统分区较小或是使用固态...

    simplescalar cache

    ### simplescalar Cache配置详解 #### 一、简述simplescalar Cache 在计算机体系结构的研究与教学中,simplescalar工具集(简称SS)是非常重要的一款工具,它提供了一种简单而有效的方法来模拟和分析处理器的行为...

    Doctrine Cache:一个使用的php缓存类库

    Doctrine Cache是PHP开发中的一个重要工具,它提供了一套完整的缓存解决方案,使得开发者可以轻松地在项目中集成缓存功能,提高应用程序的性能和响应速度。这个类库支持多种缓存后端,包括但不限于内存(如APC、...

Global site tag (gtag.js) - Google Analytics