Laravel框架中实现使用阿里云ACE缓存服务
之前我写了一篇在Laravel4框架中使用阿里云OCS缓存的文章,介绍了如何通过扩展Laravel4来支持需要SASL认证的阿里云OCS缓存服务。有网友问我,ACE的缓存怎么在Laravel4中使用。我本来觉得应该可以完全用相同的办法,后来自己尝试的时候才发现,ACE的缓存差别非常大。所以再写一篇,介绍一下如何在Laravel框架中使用阿里云ACE的缓存服务。
如何扩展Laravel的缓存驱动
在Laravel4中使用Cache::get($key),Cache::put($key,$value,$minutes)这样的代码时,实际上是访问实例化的Illuminate\Cache\Repository,所以我们通过Cache::extend方法扩展自定义缓存驱动时,同样应该返回一个Illuminate\Cache\Repository对象。
Laravel4内置的Memcached缓存驱动,实现的流程是这样的:
1.创建一个标准Memcached类的新对象
2.用上一步创建的Memcached对象创建一个实现了Illuminate\Cache\StoreInterface接口的Illuminate\Cache\MemecachedStore对象。
3.用上一步创建的MemcachedStore对象创建一个Illuminate\Cache\Repository对象。
所以我们在扩展自定义的Cache驱动时,根据自己的情况,选择上面的某一个步骤自定义,最终还是要返回Illuminate\Cache\Repository对象。比如上一篇文章中,我就是在第一步,创建标准Memcached对象之后,通过setSaslAuthData()方法设定OCS需要的用户名密码。之后第2步、第3步并不需要自定义。
ACE的缓存服务
阿里云ACE的缓存服务,跟默认的OCS有所不同:
1.通过Alibaba::Cache()方法获得Cache对象。
2.ACE的Cache对象与标准Memcached对象不同,支持的方法有限。
所以,这次第一步得到的不是标准Memcached对象,因此就不能创建Illuminate\Cache\MemcachedStore对象。需要自己实现Illuminate\Cache\StoreInterface接口。
在控制台创建了缓存空间之后,会有唯一的“缓存空间名称”,然后通过Alibaba::Cache('缓存空间名称')来获得Cache对象。以下就是实现ACE缓存服务驱动的步骤:
1.为了方便修改,我在配置文件app/config/cache.php中增加一个名为ace的键,存储缓存空间名称。
2.然后创建一个AceMemcachedStore类,这个类实现Illuminate\Cache\StoreInterface接口。
3.最后,用AceMemcachedStore对象来创建Illuminate\Cache\Repository对象。
下面来看具体的代码实现:
编码实现自定义ACE缓存驱动:
第一步,修改配置文件。打开app/config/cache.php,在最后增加一行:
//指定缓存空间名称 'ace'=>'lblog-cache',
第二步,为了方便,把自己的类文件放在src/Ace目录下,使用Ace作为命名空间。
1.在app的同级目录创建目录src/Ace。
2.打开composer.json文件,修改autoload节,在classmap下面用psr-0或者psr-4来自动加载文件。
"autoload":{ "classmap":[ //autoloadclass ], "psr-4":{ "Ace\\":"src/Ace" } },
创建src/Ace/AceMemcachedStore.php文件,代码如下:
<?php namespaceAce; useIlluminate\Cache\StoreInterface; useIlluminate\Cache\TaggableStore; classAceMemcachedStoreextendsTaggableStoreimplementsStoreInterface{ protected$memcached; protected$prefix; publicfunction__construct($space,$prefix=''){ $this->memcached=\Alibaba::Cache($space); $this->prefix=strlen($prefix)>0?$prefix.':':''; } /** *Retrieveanitemfromthecachebykey. * *@param string$key *@returnmixed */ publicfunctionget($key) { $value=$this->memcached->get($this->prefix.$key); if(is_bool($value)&&$value===false){ returnnull; } return$value; } /** *Storeaniteminthecacheforagivennumberofminutes. * *@param string$key *@param mixed$value *@param int$minutes *@returnboolean */ publicfunctionput($key,$value,$minutes) { return$this->memcached->set($this->prefix.$key,$value,$minutes); } /** *Incrementthevalueofaniteminthecache. * *@param string$key *@param mixed$value *@returnboolean */ publicfunctionincrement($key,$value=1) { return$this->memcached->increment($this->prefix.$key,$value); } /** *Decrementthevalueofaniteminthecache. * *@param string$key *@param mixed$value *@returnboolean */ publicfunctiondecrement($key,$value=1) { return$this->memcached->decrement($this->prefix.$key,$value); } /** *Storeaniteminthecacheindefinitely. * *@param string$key *@param mixed$value *@returnboolean */ publicfunctionforever($key,$value) { return$this->memcached->set($key,$value,0); } /** *Removeanitemfromthecache. * *@param string$key *@returnboolean */ publicfunctionforget($key) { return$this->memcached->delete($this->prefix.$key); } /** *Removeallitemsfromthecache. * *@returnvoid */ publicfunctionflush() { //$this->memcached->flush(); returnfalse; } publicfunctiongetMemcached() { return$this->memcached; } /** *Getthecachekeyprefix. * *@returnstring */ publicfunctiongetPrefix() { return$this->prefix; } }
这段代码比较简单,不过要特别注意一下get($key)方法的实现。标准memcached以及ACE的缓存对象的get方法都是key有效时返回对应的缓存值,否则返回false,而在Laravel4中,是通过检测get方法返回的是否null来做判断,所以这里需要处理一下,返回缓存值或者null。
AceMemcachedStore类已经创建好了,接下来在bootstrap/start.php文件中扩展Cache:
打开bootstrap/start.php,添加以下代码:
//扩展名为ace的缓存驱动 Cache::extend('ace',function($app) { //从app/config/cache.php文件中读取"ace"的值 $space=$app['config']['cache.ace']; //从app/config/cache.php文件中读取"prefix"的值 $prefix=$app['config']['cache.prefix']; //创建\Ace\AceMemcachedStore对象 $store=new\Ace\AceMemcachedStore($space,$prefix); //创建并返回\Illuminate\Cache\Repository对象 returnnew\Illuminate\Cache\Repository($store); });
指定系统使用'ace'作为缓存驱动:打开app/config/cache.php,找到'driver'=>'...'所在行,修改为:'driver'=>'ace'.
使用和限制
通过以上操作,就可以在Laravel4中调用ACE的缓存服务,使用上与平常的用法完全一致,比如:
//添加缓存,有效时间10分钟 Cache::put('my_key','myvalue',10); //读取缓存 Cache::get('my_key') //判断缓存是否存在 Cache::has('my_key') //数据查询缓存 $users=DB::table('users')->remember(10)->get();
但是由于ACE缓存对象本身的限制,只能删除指定key的缓存对象,不能遍历、全量操作,因此Cache::flush()方法就不能使用。在上面的AceMemcachedStore对象中,flush方法没有做任何操作,只是返回false.