构建自己的PHP框架--构建缓存组件(2)
2016-04-30 20:06
661 查看
上一篇博客中使用文件实现了缓存组件,这一篇我们就使用Redis来实现一下,剩下的如何使用memcache、mysql等去实现缓存我就不一一去做了。
首先我们需要安装一下 redis 和 phpredis 库,phpredis 项目在github上的地址:https://github.com/phpredis/phpredis 。相应的文档也在上面。
先在 src/cache 文件夹下创建 RedisCache.php 文件。在写组件的时候发现我们缺少一个地方去创建一个 Redis 的实例,并且是在创建 cahce 实例之后,返回给Yii::createObject 方法之前。所以我们修改了 src/Sf.php 文件,其 createObject 方法的内容如下:
对比之前的代码,不难发现其实只添加了一行
为什么选择这种做法,而不是使用判断 init 方法存不存在的方式去解决这个问题,主要是考虑到之后可能还需要对这些类做一些公共的事情,就提前抽出了 Component 类。
Component 类现在很简单,其内容如下:
之后再定义一下 Redis 缓存的配置如下:
其中 password 和 options 是选填,其它是必填。
剩下的就是相关实现,就不一一细说了,代码如下:
访问 http://localhost/simple-framework/public/index.php?r=site/cache 路径,得到结果如下:
这样我们完成了使用 Redis 的缓存组件。
好了,今天就先到这里。项目内容和博客内容也都会放到Github上,欢迎大家提建议。
code:https://github.com/CraryPrimitiveMan/simple-framework/tree/1.0
blog project:https://github.com/CraryPrimitiveMan/create-your-own-php-framework
首先我们需要安装一下 redis 和 phpredis 库,phpredis 项目在github上的地址:https://github.com/phpredis/phpredis 。相应的文档也在上面。
先在 src/cache 文件夹下创建 RedisCache.php 文件。在写组件的时候发现我们缺少一个地方去创建一个 Redis 的实例,并且是在创建 cahce 实例之后,返回给Yii::createObject 方法之前。所以我们修改了 src/Sf.php 文件,其 createObject 方法的内容如下:
public static function createObject($name) { $config = require(SF_PATH . "/config/$name.php"); // create instance $instance = new $config['class'](); unset($config['class']); // add attributes foreach ($config as $key => $value) { $instance->$key = $value; } $instance->init(); return $instance; }
对比之前的代码,不难发现其实只添加了一行
$instance->init();,这样我们就可以在 init 方法中去创建相应的 Redis 实例,并保存下来。但这样又会引入一个问题,所有使用 Yii::createObject 创建的实例都必须含有 init 方法(当然你也可以判断有没有这个方法)。那我们就来实现一个基础类 Component ,并规定所有使用 Yii::createObject 创建的实例都集成它,然后再在 Component 中加入 init 方法即可。
为什么选择这种做法,而不是使用判断 init 方法存不存在的方式去解决这个问题,主要是考虑到之后可能还需要对这些类做一些公共的事情,就提前抽出了 Component 类。
Component 类现在很简单,其内容如下:
<?php namespace sf\base; /** * Component is the base class for most sf classes. * @author Harry Sun <sunguangjun@126.com> */ class Component { /** * Initializes the component. * This method is invoked at the end of the constructor after the object is initialized with the * given configuration. */ public function init() { } }
之后再定义一下 Redis 缓存的配置如下:
<?php return [ 'class' => 'sf\cache\RedisCache', 'redis' => [ 'host' => 'localhost', 'port' => 6379, 'database' => 0, // 'password' =>'jun', // 'options' => [Redis::OPT_SERIALIZER, Redis::SERIALIZER_PHP], ] ];
其中 password 和 options 是选填,其它是必填。
剩下的就是相关实现,就不一一细说了,代码如下:
<?php namespace sf\cache; use Redis; use Exception; use sf\base\Component; /** * CacheInterface * @author Harry Sun <sunguangjun@126.com> */ class RedisCache extends Component implements CacheInterface { /** * @var Redis|array the Redis object or the config of redis */ public $redis; public function init() { if (is_array($this->redis)) { extract($this->redis); $redis = new Redis(); $redis->connect($host, $port); if (!empty($password)) { $redis->auth($password); } $redis->select($database); if (!empty($options)) { call_user_func_array([$redis, 'setOption'], $options); } $this->redis = $redis; } if (!$this->redis instanceof Redis) { throw new Exception('Cache::redis must be either a Redis connection instance.'); } } /** * Builds a normalized cache key from a given key. */ public function buildKey($key) { if (!is_string($key)) { $key = json_encode($key); } return md5($key); } /** * Retrieves a value from cache with a specified key. */ public function get($key) { $key = $this->buildKey($key); return $this->redis->get($key); } /** * Checks whether a specified key exists in the cache. */ public function exists($key) { $key = $this->buildKey($key); return $this->redis->exists($key); } /** * Retrieves multiple values from cache with the specified keys. */ public function mget($keys) { for ($index = 0; $index < count($keys); $index++) { $keys[$index] = $this->buildKey($keys[$index]); } return $this->redis->mGet($keys); } /** * Stores a value identified by a key into cache. */ public function set($key, $value, $duration = 0) { $key = $this->buildKey($key); if ($duration !== 0) { $expire = (int) $duration * 1000; return $this->redis->set($key, $value, $expire); } else { return $this->redis->set($key, $value); } } /** * Stores multiple items in cache. Each item contains a value identified by a key. */ public function mset($items, $duration = 0) { $failedKeys = []; foreach ($items as $key => $value) { if ($this->set($key, $value, $duration) === false) { $failedKeys[] = $key; } } return $failedKeys; } /** * Stores a value identified by a key into cache if the cache does not contain this key. */ public function add($key, $value, $duration = 0) { if (!$this->exists($key)) { return $this->set($key, $value, $duration); } else { return false; } } /** * Stores multiple items in cache. Each item contains a value identified by a key. */ public function madd($items, $duration = 0) { $failedKeys = []; foreach ($items as $key => $value) { if ($this->add($key, $value, $duration) === false) { $failedKeys[] = $key; } } return $failedKeys; } /** * Deletes a value with the specified key from cache */ public function delete($key) { $key = $this->buildKey($key); return $this->redis->delete($key); } /** * Deletes all values from cache. */ public function flush() { return $this->redis->flushDb(); } }
访问 http://localhost/simple-framework/public/index.php?r=site/cache 路径,得到结果如下:
我就是测试一下缓存组件
这样我们完成了使用 Redis 的缓存组件。
好了,今天就先到这里。项目内容和博客内容也都会放到Github上,欢迎大家提建议。
code:https://github.com/CraryPrimitiveMan/simple-framework/tree/1.0
blog project:https://github.com/CraryPrimitiveMan/create-your-own-php-framework
相关文章推荐
- sublime text 配置php调试环境(快捷键)
- php判断图片的格式
- 2008 R2 创建FTP 一不小心踩到巨坑
- 【php】socket编程基础知识
- php中构造函数和析构函数
- PHP基础数组操作(二)
- thinkPHP的<eq>标签
- php生成印章 代码片段
- Win10 取消开机密码 (netplwiz没用)
- PHP经典算法小羊繁殖
- empty与isset的用法及区别(转载)
- PHP开发常见的页面跳转技术
- PHP导出EXCEL
- PHP基础数组操作(一)
- php file_put_contents() 读取数据不换行问题
- 小白工程师 html+php+mysql 实例
- vtk实战(三十一)——写入vtp数据
- ftp
- PHP字符串常用函数
- 用PHP编写Hadoop的MapReduce程序