Yii2框架redis key前缀可以配置吗

场景
由于和其他部分公用了redis。除了规定库,还需要在我们项目的所有key前面增加一个webapp:的前缀。
我现在是在params.php配置了一个'redis.prefix' => 'webapp:'

然后业务代码里使用`Yii::$app->paramas['redis.prefix']。虽然可以,但是总感觉不舒服。

那么我想问下 yii2中有没有配置或者可以实现透明的key存储,然后自动加webapp:这个前缀

谢谢大家。

阅读 5.4k
1 个回答

1. 如果只是单纯地使用Redis作为cache组件:

'components' => [
    'cache' => [
        'class' => 'yii\redis\Cache',
    ],
],

只需要在配置文件中添加 keyPrefix 属性即可:

'components' => [
    'cache' => [
        'class' => 'yii\redis\Cache',
        'keyPrefix' => 'webapp:'
    ],
]

2. 如果是直接使用Redis组件:

'components' => [
    'redis' => [
        'class' => 'yii\redis\Connection',
        'hostname' => 'localhost',
        'port' => 6379,
        'database' => 0,
    ],
],

这样就没有办法实现自动加前缀,只能自己去实现。

如果是我的话,我会单独写一个Redis的helper类,只在这个 Redis helper类中调用 \Yii::$app->redis 组件。

Redis 基础类,放一些基础方法,各个数据类型都适用,每个数据类型都编写一个子类,继承这个类

class RedisBase
{
    /**
     * 这个方法中给 key 增加前缀
     * 所有与key相关的方法都要调用这个方法
     * @param $key
     * @return string
     */
    protected static function buildKey($key)
    {
        return \Yii::$app->params['redis.prefix'] . $key;
    }

    /**
     * @return \yii\redis\Connection
     */
    protected static function getRedis()
    {
        return \Yii::$app->redis;
    }

    /**
     * # exists key
     *
     * 检查key是否存在
     * @param string $key
     * @return bool
     */
    public static function exists($key)
    {
        $key = self::buildKey($key);
        $redis = self::getRedis();
        return (bool) $redis->exists($key);
    }

    /**
     * # del key [key2 key3 …]
     *
     * 删除指定数据
     *
     * @param string $key
     * @param bool $strict
     * 是否使用严格模式
     * true: 当指定键不存在时,返回false
     * false: 当指定键不存在时,但会true
     * @return bool
     */
    public static function del($key, $strict = false)
    {
        $key = self::buildKey($key);

        // 非严格模式,当指定键不存在时,但会true
        if (! $strict && ! self::exists($key)) return true;

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

    /**
     * # expire key seconds
     *
     * 设置 key在seconds秒后过期
     *
     * @param $key
     * @param $seconds
     * @return bool
     */
    public static function expire($key, $seconds)
    {
        $key = self::buildKey($key);
        $redis = self::getRedis();
        return (bool) $redis->expire($key, $seconds);
    }

    /**
     * # ttl key
     *
     * 大于等于0时,表示剩余过期秒数
     * -1 表示key存在,并且没有过期时间
     * -2 表示key已经不存在了
     *
     * 查看key的剩余过期时间
     * @param $key
     * @return int
     */
    public static function ttl($key)
    {
        $key = self::buildKey($key);
        $redis = self::getRedis();
        return (int) $redis->ttl($key);
    }

    /**
     * # dbsize
     *
     * 当前db 键的总数量
     * @return int
     */
    public static function dbSize()
    {
        $redis = self::getRedis();
        return (int) $redis->dbsize();
    }

    // ... 其他redis基础方法
}

Redis 字符串类型的方法,单独放置在RedisString类中,继承 RedisBase 方法

class RedisString extends RedisBase
{

    /**
     * # SET key value options
     *
     * 设置指定 key 的值
     *
     * @param $key
     * @param $value
     * @param array $options
     *
     * EX seconds -- 设置指定key的过期时间,以秒为单位
     * PX milliseconds -- 设置指定key的过期时间,以毫秒为单位
     * NX -- 只有在key不存在的情况下才设置.
     * XX -- 只有在key存在的情况下才设置.
     *
     * eg: ['NX', 'EX', '3600']
     *
     * @return bool
     */
    public static function set($key, $value, array $options = [])
    {
        $key = self::buildKey($key);
        $redis = self::getRedis();
        $param = array_merge([$key, $value], $options);
        return (bool) call_user_func_array([$redis, 'set'], $param);
    }

    /**
     * # GET key
     *
     * 获取指定 key 的值。
     * @param $key
     * @return string
     */
    public static function get($key)
    {
        $key = self::buildKey($key);
        $redis = self::getRedis();
        return $redis->get($key);
    }

    // ...其他String类型的方法
}

Redis 集合类型的方法,单独放置在RedisSet类中,继承 RedisBase 方法

class RedisSet extends RedisBase
{
    /**
     * # SADD key member1 [member2]
     *
     * 向集合添加一个或多个成员
     *
     * @param $key
     * @param $members
     * @return int 成功添加数量
     */
    public static function sAdd($key, $members)
    {
        $key = self::buildKey($key);
        $redis = self::getRedis();

        // php >= 5.6
        return (int) $redis->sadd($key, ...(array) $members);

        // 通用写法
//        $params = array_merge([$key], (array) $members);
//        return (int) call_user_func_array([$redis, 'sadd'], $params);
    }

    /**
     * # SREM key member1 [member2]
     *
     * 移除集合中一个或多个成员
     * @param $key
     * @param $members
     * @return int
     */
    public static function sRem($key, $members)
    {
        $key = self::buildKey($key);
        $redis = self::getRedis();

        $params = array_merge([$key], (array) $members);
        return (int) call_user_func_array([$redis, 'srem'], $params);
    }

    /**
     * # SISMEMBER key member
     *
     * 判断 member 元素是否是集合 key 的成员
     * @param $key
     * @param $member
     * @return bool
     */
    public static function sIsMember($key, $member)
    {
        $key = self::buildKey($key);
        $redis = self::getRedis();

        return (bool) $redis->sismember($key, $member);
    }

    /**
     * # SMEMBERS key
     *
     * 返回集合中的所有成员
     * @param $key
     * @return array
     */
    public static function sMembers($key)
    {
        $key = self::buildKey($key);
        $redis = self::getRedis();

        return $redis->smembers($key);
    }

    /**
     * # SCARD key
     *
     * 获取集合的成员数
     * @param $key
     * @return bool
     */
    public static function sCard($key)
    {
        $key = self::buildKey($key);
        $redis = self::getRedis();

        return (int) $redis->scard($key);
    }
    
    // ...其他Set类型的方法

Redis 有序集合类型的方法,单独放置在RedisSortedSet类中,继承 RedisBase 方法

class RedisSortedSet extends RedisBase
{
    /**
     * # ZADD key score1 member1 [score2 member2]
     *
     * 向有序集合添加一个或多个成员,或者更新已存在成员的分数
     * @param $key
     * @param array $options
     * [
     *     'value1' => score1,
     *     'value2' => score2,
     *     'value3' => score3,
     * ]
     *
     * @return int
     */
    public static function zAdd($key, array $options)
    {
        $key = self::buildKey($key);
        $redis = self::getRedis();
        $param = [$key];

        foreach ($options as $value => $score) {
            $param[] = $score;
            $param[] = $value;
        }

        return (int) call_user_func_array([$redis, 'zadd'], $param);
    }
    
    // ...其他SortedSet类型的方法
}

Redis List类型的方法,单独放置在RedisList类中,继承 RedisBase 方法

class RedisList extends RedisBase
{
    // ...方法省略
}

Redis Hash类型的方法,单独放置在RedisHash类中,继承 RedisBase 方法

class RedisHash extends RedisBase
{
    // ...方法省略
}

这样写的好处:

1.在调用redis的原始方法前,可以对数据进行预处理
2.后期维护方便,若想修改,只需要修改这里的方法即可
3.方便添加一些注释信息
4.这种方法对IDE更友好,可以直接跳转到这个类中的方法,若处处使用 \Yii::$app->redis,则会比较难维护

另外,关于Redis的一些数据类型,可以查看Redis学习笔记 - 数据类型与API

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
宣传栏