之前我写了一篇在 Laravel 4 框架中使用阿里云 OCS 缓存的文章,介绍了如何通过扩展 Laravel 4 来支持需要 SASL 认证的阿里云 OCS 缓存服务。有网友问我,ACE 的缓存怎么在 Laravel 4 中使用。我本来觉得应该可以完全用相同的办法,后来自己尝试的时候才发现,ACE 的缓存差别非常大。所以再写一篇,介绍一下如何在 Laravel 框架中使用阿里云 ACE 的缓存服务。
如何扩展 Laravel 的缓存驱动
在 Laravel 4 中使用 Cache::get($key)
, Cache::put($key, $value, $minutes)
这样的代码时,实际上是访问 实例化的 Illuminate\Cache\Repository, 所以我们通过 Cache::extend
方法扩展自定义缓存驱动时,同样应该返回一个 Illuminate\Cache\Repository 对象。
Laravel 4 内置的 Memcached 缓存驱动,实现的流程是这样的:
- 创建一个标准 Memcached 类的新对象
- 用上一步创建的 Memcached 对象创建一个实现了 Illuminate\Cache\StoreInterface 接口的 Illuminate\Cache\MemecachedStore 对象。
- 用上一步创建的 MemcachedStore 对象创建一个 Illuminate\Cache\Repository 对象。
所以我们在扩展自定义的 Cache 驱动时,根据自己的情况,选择上面的某一个步骤自定义,最终还是要返回 Illuminate\Cache\Repository 对象。比如上一篇文章中,我就是在第一步,创建标准 Memcached 对象之后,通过 setSaslAuthData() 方法设定 OCS 需要的用户名密码。之后第2步、第3步并不需要自定义。
ACE 的缓存服务
阿里云 ACE 的缓存服务,跟默认的 OCS 有所不同:
- 通过 Alibaba::Cache() 方法获得 Cache 对象。
- ACE 的 Cache 对象与标准 Memcached 对象不同,支持的方法有限。
所以,这次第一步得到的不是标准 Memcached 对象,因此就不能创建 Illuminate\Cache\MemcachedStore 对象。需要自己实现 Illuminate\Cache\StoreInterface 接口。
在控制台创建了缓存空间之后,会有唯一的“缓存空间名称”,然后通过 Alibaba::Cache('缓存空间名称')
来获得 Cache 对象。以下就是实现 ACE 缓存服务驱动的步骤:
- 为了方便修改,我在配置文件 app/config/cache.php 中增加一个名为 ace 的键,存储缓存空间名称。
- 然后创建一个 AceMemcachedStore 类,这个类实现 Illuminate\Cache\StoreInterface 接口。
- 最后,用 AceMemcachedStore 对象来创建 Illuminate\Cache\Repository 对象。
下面来看具体的代码实现:
编码实现自定义 ACE 缓存驱动:
第一步,修改配置文件。打开 app/config/cache.php,在最后增加一行:
// 指定缓存空间名称 'ace' => 'lblog-cache',
第二步,为了方便,把自己的类文件放在 src/Ace 目录下,使用 Ace 作为命名空间。
- 在 app 的同级目录创建目录 src/Ace。
- 打开 composer.json 文件,修改 autoload 节,在 classmap 下面用 psr-0 或者 psr-4 来自动加载文件。
"autoload": { "classmap": [ // autoload class ], "psr-4": { "Ace\\": "src/Ace" } },
- 创建 src/Ace/AceMemcachedStore.php 文件,代码如下:
<?php namespace Ace; use Illuminate\Cache\StoreInterface; use Illuminate\Cache\TaggableStore; class AceMemcachedStore extends TaggableStore implements StoreInterface { protected $memcached; protected $prefix; public function __construct($space, $prefix = '') { $this->memcached = \Alibaba::Cache($space); $this->prefix = strlen($prefix) > 0 ? $prefix.':' : ''; } /** * Retrieve an item from the cache by key. * * @param string $key * @return mixed */ public function get($key) { $value = $this->memcached->get($this->prefix.$key); if(is_bool($value) && $value === false) { return null; } return $value; } /** * Store an item in the cache for a given number of minutes. * * @param string $key * @param mixed $value * @param int $minutes * @return boolean */ public function put($key, $value, $minutes) { return $this->memcached->set($this->prefix.$key, $value, $minutes); } /** * Increment the value of an item in the cache. * * @param string $key * @param mixed $value * @return boolean */ public function increment($key, $value = 1) { return $this->memcached->increment($this->prefix.$key, $value); } /** * Decrement the value of an item in the cache. * * @param string $key * @param mixed $value * @return boolean */ public function decrement($key, $value = 1) { return $this->memcached->decrement($this->prefix.$key, $value); } /** * Store an item in the cache indefinitely. * * @param string $key * @param mixed $value * @return boolean */ public function forever($key, $value) { return $this->memcached->set($key, $value, 0); } /** * Remove an item from the cache. * * @param string $key * @return boolean */ public function forget($key) { return $this->memcached->delete($this->prefix.$key); } /** * Remove all items from the cache. * * @return void */ public function flush() { //$this->memcached->flush(); return false; } public function getMemcached() { return $this->memcached; } /** * Get the cache key prefix. * * @return string */ public function getPrefix() { return $this->prefix; } }
这段代码比较简单,不过要特别注意一下 get($key)
方法的实现。标准 memcached 以及 ACE 的缓存对象的 get
方法都是key有效时返回对应的缓存值,否则返回false,而在 Laravel 4 中,是通过检测 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 对象 return new \Illuminate\Cache\Repository($store); });
- 指定系统使用 ‘ace’ 作为缓存驱动:打开 app/config/cache.php,找到
'driver' => '...'
所在行,修改为:'driver' => 'ace'
.
使用和限制
通过以上操作,就可以在 Laravel 4 中调用 ACE 的缓存服务,使用上与平常的用法完全一致,比如:
// 添加缓存,有效时间10分钟 Cache::put('my_key', 'my value', 10); // 读取缓存 Cache::get('my_key') // 判断缓存是否存在 Cache::has('my_key') // 数据查询缓存 $users = DB::table('users')->remember(10)->get();
但是由于 ACE 缓存对象本身的限制,只能删除指定 key 的缓存对象,不能遍历、全量操作,因此 Cache::flush()
方法就不能使用。在上面的 AceMemcachedStore 对象中,flush 方法没有做任何操作,只是返回 false
.
作者:小李刀刀
原文链接:在 Laravel 4 框架中使用阿里云 ACE 的缓存服务
裁纸刀下版权所有,允许非商业用途转载,转载时请原样转载并标明来源、作者,保留原文链接。
你好,我正在学习Laravel正好看到你这篇关于使用Ace 的文章,按照你的步骤进行了改写,但是运行的时候显示‘Class ‘AceAceMemcachedStore’ not found’,我使用的是 Laravel 4.2,想请问下,这是怎么回事
我在学laravel,也准备使用阿里云,文章先收起来了。
我在学laravel,也准备使用阿里云,文章先收起来了。