Laravel中扩展Memcached缓存驱动实现使用阿里云OCS缓存


Posted in PHP onFebruary 10, 2015

Laravel 是我最近用得非常多而且越用就越喜欢的一款PHP框架,由于没有向下兼容的历史包袱,完全面向对象的风格,借助 Facades 优雅的IoC Container 实现,采用 Composer 进行包管理,可以方便地引入和使用开源社区里的优秀组件……总而言之,这是一款真正让你能够 "code happy" 的“巨匠级PHP开发框架”。

在尝试把自己的 Laravel App 部署到阿里云的时候,遇到了一个问题: Laravel 支持 Memcached 缓存,阿里云的 OCS 也是基于 Memcached 的缓存,但是阿里云 OCS 采用 SASL 认证,而 Laravel 的 Memcached 驱动并没有实现相关的方法,即使在服务器上编译PHP Memcached 的时候启用了 SASL 认证选项,也没办法设定用户名和密码。

在 Laravel 中,解决这样的问题,有很多方法。我选择了最快捷最省事的方法:扩展 Laravel 自己的 Memcached 驱动,通过 Memcached 对象自身的 setSaslAuthData 方法,指定用户名和密码。

背景知识

这是利用了 Illuminate\Cache\CacheManager 的 extend 方法(继承自Illuminate\Support\Manager)。先看一下这个方法的定义:

/**

 * Register a custom driver creator Closure.

 *

 * @param  string   $driver

 * @param  Closure  $callback

 * @return \Illuminate\Support\Manager|static

 */

public function extend($driver, Closure $callback){}

这个方法接收两个参数,第一个是代表你自定义的驱动名称的字符串,第二个是一个闭包回调函数,这个函数就是当调用你的自定义驱动时要执行的方法。通过阅读 Illuminate\Cache\CacheManager 的源代码,我们可以发现创建驱动的函数要返回一个 Illuminate\Cache\Repository 的实例,Illuminate\Cache\Repository 的构造函数如下:
/**

 * Create a new cache repository instance.

 *

 * @param  \Illuminate\Cache\StoreInterface  $store

 */

public function __construct(StoreInterface $store)

{

    $this->store = $store;

}

它需要一个实现了 Illuminate\Cache\StoreInterface 接口的对象,这个接口中定义了 Cache 对象能够执行的方法。由于我计划是扩展原有的 Memcached 缓存驱动,在 Illuminate\Cache\CacheManager 的源代码中,可以看到 Laravel 是这样创建 Memcached 驱动的:

/**

 * Create an instance of the Memcached cache driver.

 *

 * @return \Illuminate\Cache\MemcachedStore

 */

protected function createMemcachedDriver()

{

    $servers = $this->app['config']['cache.memcached'];

 

    $memcached = $this->app['memcached.connector']->connect($servers);

 

    return $this->repository(new MemcachedStore($memcached, $this->getPrefix()));

}

它先从配置文件中读取你定义的 Memcached 服务器,然后创建一个 Memcached 对象(通过 Illuminate\Cache\MemcachedConnector 实现,实际上就是创建一个标准的 Memcached 对象,然后调用 Memcached 的 addServer 方法来指定要连接的服务器,然后返回实例化的 Memcached 对象。)

扩展自己的缓存驱动

了解了上述的背景知识之后,就可以来扩展自己的缓存驱动了。思路如下:

1.在 app/config/cache.php 文件中,增加三个配置项,用来设定“是否使用sasl认证”,“sasl认证账户”,“sasl认证密码”。
2.在 bootstrap/start.php 文件中,调用 Cache::extend 方法扩展驱动。
3.在 app/config/cache.php 文件中,修改 driver 配置项,指定系统使用自己扩展的驱动。

增加配置项

首先,打开 app/config/cache.php 文件,找到:

'memcached' => array(

        array('host' => '127.0.0.1', 'port' => 11211, 'weight' => 100),

    ),

修改为:
'memcached' => array(

        array('host' => '127.0.0.1', 'port' => 11211, 'weight' => 100),

    ),

 

    'memcached_sasl' => 'true', // 启用sasl认证

    'memcached_user' => 'your ocs username', // 你的 OCS 用户名

    'memcached_pass' => 'your ocs password', // 你的 OCS 密码

扩展驱动

然后,打开 bootstrap/start.php 文件,在最后一行 return $app; 前面插入代码:

// 基于系统自己的 Memcached 缓存驱动,扩展一个名为 saslMemcached 的缓存驱动

Cache::extend('saslMemcached', function($app){

    // 从配置文件中读取 Memcached 服务器配置

    $servers = $app['config']['cache.memcached'];

     

    // 利用 Illuminate\Cache\MemcachedConnector 类来创建新的 Memcached 对象

    $memcached = $app['memcached.connector']->connect($servers);

 

    // 如果服务器上的 PHP Memcached 扩展支持 SASL 认证

    if(ini_get('memcached.use_sasl')){

         

        // 从配置文件中读取 sasl 认证用户名

        $user = $app['config']['cache.memcached_user'];

 

        // 从配置文件中读取 sasl 认证密码

        $pass = $app['config']['cache.memcached_pass'];

         

        // 禁用 Memcached 压缩 (阿里云的文档里这样做了……)

        $memcached->setOption(Memcached::OPT_COMPRESSION, false);

 

        // 指定 Memcached 使用 binary protocol ( sasl 认证要求 )

        $memcached->setOption(Memcached::OPT_BINARY_PROTOCOL, true);

 

        // 指定用于 sasl 认证的账号密码

        $memcached->setSaslAuthData($user, $pass);

    }

 

    // 从配置文件中读取缓存前缀

    $prefix = $app['config']['cache.prefix'];

 

    // 创建 MemcachedStore 对象

    $store = new \Illuminate\Cache\MemcachedStore($memcached, $prefix);

     

    // 创建 Repository 对象,并返回

    return new \Illuminate\Cache\Repository($store);

});

修改配置,使用自己扩展的缓存驱动

打开 app/config/cache.php 文件,找到:

"driver" => "file", // 默认是使用文件缓存

修改为:
"driver" => "saslMemcached", // 刚才扩展实现的驱动名称

现在,你就可以在你的 阿里云 ECS 服务器上, 让 Laravel 使用 阿里云 OCS 缓存服务了。(前提是你的 PHP 支持 Memcached 扩展,并且启用了 SASL 认证,参考:http://help.aliyun.com/doc/view/13553932.html
PHP 相关文章推荐
如何实现给定日期的若干天以后的日期
Oct 09 PHP
php 缓存函数代码
Aug 27 PHP
使用PHP实现二分查找算法代码分享
Jun 24 PHP
关于二级目录拖拽排序的实现(源码示例下载)
Apr 26 PHP
php fsockopen解决办法 php实现多线程
Jan 20 PHP
php判断类是否存在函数class_exists用法分析
Nov 14 PHP
php截取指定2个字符之间字符串的方法
Apr 15 PHP
PHP几个实用自定义函数小结
Jan 25 PHP
WordPress的文章自动添加关键词及关键词的SEO优化
Mar 01 PHP
php利用递归实现删除文件目录的方法
Sep 23 PHP
php微信公众号开发之微信企业付款给个人
Oct 04 PHP
解决php用mysql方式连接数据库出现Deprecated报错问题
Dec 25 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
自己写的php中文截取函数mb_strlen和mb_substr
Feb 09 #PHP
You might like
php过滤所有的空白字符(空格、全角空格、换行等)
2015/10/27 PHP
PHP多维数组遍历方法(2种实现方法)
2015/12/10 PHP
php使用timthumb生成缩略图的方法
2016/01/22 PHP
php图片添加文字水印实现代码
2016/03/15 PHP
PHP unset函数原理及使用方法解析
2020/08/14 PHP
半角全角相互转换的js函数
2009/10/16 Javascript
需要做特殊处理的DOM元素属性的访问
2010/11/05 Javascript
jQuery的12招常用技巧分享
2011/08/08 Javascript
Extjs中ComboBoxTree实现的下拉框树效果(自写)
2013/05/28 Javascript
IE6中链接A的href为javascript协议时不在当前页面跳转
2014/06/05 Javascript
JavaScript setTimeout使用闭包功能实现定时打印数值
2015/12/18 Javascript
JavaScript判断对象是否为数组
2015/12/22 Javascript
Node.js Addons翻译(C/C++扩展)
2016/06/12 Javascript
纯前端JavaScript实现Excel IO案例分享
2016/08/26 Javascript
JavaScript中offsetWidth的bug及解决方法
2017/05/17 Javascript
vue 运用mock数据的示例代码
2017/11/07 Javascript
Bootstrap标签页(Tab)插件切换echarts不显示问题的解决
2018/07/13 Javascript
vue中promise的使用及异步请求数据的方法
2018/11/08 Javascript
ElementUI Tag组件实现多标签生成的方法示例
2019/07/08 Javascript
解决vux 中popup 组件Mask 遮罩在最上层的问题
2020/11/03 Javascript
jquery实现点击左右按钮切换图片
2021/01/27 jQuery
Python的加密模块md5、sha、crypt使用实例
2014/09/28 Python
Python实现对excel文件列表值进行统计的方法
2015/07/25 Python
Python爬虫抓取手机APP的传输数据
2016/01/22 Python
用python记录运行pid,并在需要时kill掉它们的实例
2017/01/16 Python
python+matplotlib绘制简单的海豚(顶点和节点的操作)
2018/01/02 Python
python3 图片referer防盗链的实现方法
2018/03/12 Python
keras 两种训练模型方式详解fit和fit_generator(节省内存)
2020/07/03 Python
python如何利用paramiko执行服务器命令
2020/11/07 Python
HTML5利用约束验证API来检查表单的输入数据的代码实例
2016/12/20 HTML / CSS
维多利亚的秘密官方旗舰店:VICTORIA’S SECRET
2018/04/02 全球购物
聘用意向书范本
2014/04/01 职场文书
秋天的图画教学反思
2014/05/01 职场文书
经济国贸专业求职信
2014/06/18 职场文书
三行辞职书范文
2015/02/26 职场文书
OpenFeign实现远程调用
2022/08/14 Java/Android