设为首页 收藏本站
查看: 532|回复: 0

[经验分享] 实用PHP技巧:万能Cache

[复制链接]

尚未签到

发表于 2017-3-30 09:42:12 | 显示全部楼层 |阅读模式
  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本身还不完善,有很多提升的余地,比如说缓存时间的设置,或者内容更新时如何通过观察者模式的方式来完成缓存的主动更新等等,这些问题我就不得瑟了,留给读者自己思考。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-357430-1-1.html 上篇帖子: php点击保存excel文件 下篇帖子: php几个数组函数
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表