Laravel框架中实现使用阿里云ACE缓存服务


Posted in PHP onFebruary 10, 2015

之前我写了一篇在 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 缓存驱动,实现的流程是这样的:

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": [

        // 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.

PHP 相关文章推荐
介绍php设计模式中的工厂模式
Jun 12 PHP
解析php中var_dump,var_export,print_r三个函数的区别
Jun 21 PHP
php通过字符串调用函数示例
Mar 02 PHP
php中运用http调用的GET和POST方法示例
Sep 29 PHP
PHP获取文件相对路径的方法
Feb 26 PHP
带你了解PHP7 性能翻倍的关键
Nov 19 PHP
Yii2单元测试用法示例
Nov 12 PHP
详解Yii2 定制表单输入字段的标签和样式
Jan 04 PHP
PHP实现基于栈的后缀表达式求值功能
Nov 10 PHP
PHP的mysqli_ssl_set()函数讲解
Jan 23 PHP
使用PHPUnit进行单元测试并生成代码覆盖率报告的方法
Mar 08 PHP
php的单例模式及应用场景详解
Feb 27 PHP
Laravel中扩展Memcached缓存驱动实现使用阿里云OCS缓存
Feb 10 #PHP
PHP框架Laravel的小技巧两则
Feb 10 #PHP
Laravel模板引擎Blade中section的一些标签的区别介绍
Feb 10 #PHP
Laravel 5.0 发布 新版本特性详解
Feb 10 #PHP
PHP转盘抽奖接口实例
Feb 09 #PHP
PHP积分兑换接口实例
Feb 09 #PHP
PHP答题类应用接口实例
Feb 09 #PHP
You might like
Fatal error: Call to undefined function curl_init()解决方法
2010/04/09 PHP
PHP生成excel时单元格内换行问题的解决方法
2010/08/26 PHP
PHP反射机制用法实例
2014/08/28 PHP
PHP+APACHE实现网址伪静态
2015/02/22 PHP
php+ajax实现带进度条的上传图片功能【附demo源码下载】
2016/09/14 PHP
PHP的Json中文处理解决方案
2016/09/29 PHP
Ajax中的JSON格式与php传输过程全面解析
2017/11/14 PHP
大家未必知道的Js技巧收藏
2008/04/07 Javascript
JavaScript DOM学习第六章 表单实例
2010/02/19 Javascript
jQuery与其它库冲突的解决方法
2010/06/25 Javascript
jquery 插件学习(五)
2012/08/06 Javascript
JS阻止冒泡事件以及默认事件发生的简单方法
2014/01/17 Javascript
9款2014最热门jQuery实用特效推荐
2014/12/07 Javascript
JavaScript中的变量作用域介绍
2014/12/31 Javascript
浅谈利用JavaScript进行的DDoS攻击原理与防御
2015/06/04 Javascript
深入理解javascript作用域第二篇之词法作用域和动态作用域
2016/07/24 Javascript
基于angular中的重要指令详解($eval,$parse和$compile)
2016/10/21 Javascript
几种tab切换详解
2017/02/03 Javascript
Angularjs实现上传图片预览功能
2017/09/01 Javascript
JS获取当前地理位置的方法
2017/10/25 Javascript
(模仿京东用户注册)用JQuery实现简单表单验证,初学者必看
2018/01/08 jQuery
浅析JS中回调函数及用法
2018/07/25 Javascript
Vue $attrs &amp; inheritAttr实现button禁用效果案例
2020/12/07 Vue.js
Vue在H5 项目中使用融云进行实时个人单聊通讯
2020/12/14 Vue.js
python3+mysql查询数据并通过邮件群发excel附件
2018/02/24 Python
使用pyshp包进行shapefile文件修改的例子
2019/12/06 Python
OpenCV Python实现图像指定区域裁剪
2021/03/12 Python
奥地利时尚、美容、玩具和家居之家:Kastner & Öhler
2020/04/26 全球购物
甜品蛋糕店创业计划书范文
2014/02/06 职场文书
爱耳日活动总结
2014/04/30 职场文书
2014年党员学习“三严三实”思想汇报
2014/09/15 职场文书
拾金不昧表扬稿
2015/01/16 职场文书
Python+Tkinter制作专属图形化界面
2022/04/01 Python
Python OpenCV形态学运算示例详解
2022/04/07 Python
解决Springboot PostMapping无法获取数据的问题
2022/05/06 Java/Android
pandas中pd.groupby()的用法详解
2022/06/16 Python