(三)Redis 缓存 - 利用 Composer 完善自己的 PHP 框架【完结】

分享 johnlui ⋅ 于 3年前 ⋅ 最后回复由 johnlui 3年前 ⋅ 5752 阅读

说明

原文发表在我的个人网站:利用 Composer 完善自己的 PHP 框架(三)——Redis 缓存

本教程示例代码见 https://github.com/johnlui/My-First-Framework-based-on-Composer

回顾

上两篇文章中我们完成了 View 视图加载类和 Mail 邮件发送类的设计,完成了两个可插拔组件。本篇文章中我们将构建另一个可插拔组件——Redis 接口,并使用它构建 MFFC 的高速缓存服务。

正文

Redis 简介

Redis 是一个高性能的 key-value 数据库,其 value 支持 StringMap(Hash)listsetsorted sets,中文翻译为 字符串、字典(哈希,在世界上最好的语言PHP 中属于 数组 的一部分)、列表、集合和有序集合。

我们可以用 Redis 作为高速缓存,存放系统经常需要访问的数据。相比使用文件作为缓存,Redis 拥有更高的性能、更好地可维护性和更强大的操作 API。

Redis 安装

Redis 官网为 http://redis.io/,可以很容易地下载安装并在命令行直接启动,它默认监听 6379 端口。

Redis 服务端装好并启动之后,并不能写一行代码直接开始使用了,我们还需要安装 客户端。目前有两种方式比较推荐:

  1. 安装 PHP 的 Redis 扩展
  2. 使用 nrk/predis 包。

注意:作为 PHP 扩展安装时,请先打印出 phpinfo(),找到 Loaded Configuration File 这一项,编辑这个 php.ini 才有效。别忘了 重启 Apache 或者 php-fpm。

Redis 使用

我们在此选择 nrk/predis 包作为 Redis 驱动。编辑 composer.json

"require": {
  "codingbean/macaw": "dev-master",
  "illuminate/database": "*",
  "filp/whoops": "*",
  "nette/mail": "*",
  "predis/predis": "*"
},

运行 composer update,等待安装完成。

然后我们就要开始构建 Redis 类了,新建 services/Redis.php

<?php

use Predis\Client;

/**
* \Redis
*/
class Redis
{
  const CONFIG_FILE = '/config/redis.php';
  protected static $redis;

  public static function init()
  {
    self::$redis = new Client(require BASE_PATH.self::CONFIG_FILE);
  }

  public static function set($key,$value,$time=null,$unit=null)
  {
    self::init();
    if ($time) {

      switch ($unit) {
        case 'h':
          $time *= 3600;
          break;
        case 'm':
          $time *= 60;
          break;
        case 's':
        case 'ms':
          break;

        default:
          throw new InvalidArgumentException('单位只能是 h m s ms');
          break;
      }

      if ($unit=='ms') {
        self::_psetex($key,$value,$time);
      } else {
        self::_setex($key,$value,$time);
      }

    } else {

      self::$redis->set($key,$value);

    }
  }

  public static function get($key)
  {
    self::init();

    return self::$redis->get($key);
  }

  public static function delete($key)
  {
    self::init();

    return self::$redis->del($key);
  }

  private static function _setex($key,$value,$time)
  {
    self::$redis->setex($key,$time,$value);
  }

  private static function _psetex($key,$value,$time)
  {
    self::$redis->psetex($key,$time,$value);
  }
}

新建配置文件 config/redis.php

<?php

return [
  'host' => '127.0.0.1',
  'port' => 6379
];

然后我们就可以开始测试啦~ 在 HomeController 中增加:

Redis::set('key','value',5,'s');
echo Redis::get('key');

运行一次后将上面一行注释掉,不断刷新,看 value 是否会在设定的时间结束后从页面上消失。

代码分析

  1. 我们创建了 \Redis 类,提供了 ::set()::get()::delete() 三个静态方法,用于新增、获取和删除一对 key-value
  2. ::set() 方法支持设定 key-value 键值对的生命周期,并支持 hmsms 四个单位,代表时、分、秒和毫秒,这样就可以方便地用于缓存了。
  3. 严格意义上讲,缓存类至少还需要一个 判断 key 是否还存在 的基本操作,所以这个类还只是一个略微强大的 Redis 接口。
  4. 建造缓存接口作为练习,大家可以尝试自己动手写一下。选择新建 Cache 类或者在 Redis 类中新增接口均可。

【完结】

本帖已被设为精华帖!
回复数量: 6
  • Summer MOD A Life-long learner.
    3年前

    我修改了头部为尾部的地方, 加了 说明 和 预告 两部分, 对了, 还有 Title 也被我修改了, 为了加精华首页显示的时候好看点. :smile:

  • Summer MOD A Life-long learner.
    3年前

    每天早上 6 点多起来的时候, 都能看到 @johnlui 的发帖时间是 3个小时前 , 楼主是用生命在写文章呀. :+1:

  • Summer MOD A Life-long learner.
    3年前

    建议使用加 Branch 的方式来区分不同文章里面的源码, 如: 第一篇取名 lesson_1 的 branch, 第二就是 lesson_2 etc...

    这样阅读文章的人, 在看第一篇文章的时候, 选择查看 lesson_1 就能看到对应的代码. :sunglasses:

  • johnlui
    3年前

    @Summer 最近在家闲着,睡得比较晚。。。branch我怕一些人不会使,毕竟大多数真正要看代码来学习的人基本都只会下载zip。。。

  • 乌龙球
    3年前

    感谢对新鸟的体贴关照。

  • johnlui
    3年前

    @乌龙球 不客气~

暂无评论~~
  • 请注意单词拼写,以及中英文排版,参考此页
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`, 更多语法请见这里 Markdown 语法
  • 支持表情,使用方法请见 Emoji 自动补全来咯,可用的 Emoji 请见 :metal: :point_right: Emoji 列表 :star: :sparkles:
  • 上传图片, 支持拖拽和剪切板黏贴上传, 格式限制 - jpg, png, gif
  • 发布框支持本地存储功能,会在内容变更时保存,「提交」按钮点击时清空
  请勿发布不友善或者负能量的内容。与人为善,比聪明更重要!
Ctrl+Enter