正確優雅的在ThinkPHP5中使用redis

TP5的redis驅動在項目中使用遇到的問題

  1. 緩存的Key前綴取的是config中配置的,沒有單獨管理。
  2. 不能使用redis一些本身高級命令,比如sadd等。
  3. 一些常用的操作可以再次封裝,比如分佈式鎖等。

key的管理類

key要統一管理起來,便於後續的閱讀以及擴展

<?php

namespace libs;

/**
 * 緩存key映射類:緩存KEY要統一配置,便於後期批量更改和管理
 * 注意其命名規則: 項目名:模塊名:名稱:類型   tkmall:mem:uid:hash
 * Class CacheKeyMap
 * @package libs
 */
class CacheKeyMap
{
    public static $prefix = 'tkmall:';

    /**
     * 基於會員uid的hash,管理會員資料
     * @param $uid
     * @param int $prefix
     * @return string
     */
    public static function memberUidHash($uid,$prefix=0)
    {
        if($prefix){
            // 用於keys,scan等命令
            return self::$prefix . 'mem:' . $uid .':*';
        }
        return self::$prefix . 'mem:' . $uid .':hash';
    }
}

libsRedis

<?php

namespace libs;
use think\cache\driver\Redis as tpRedis;

/**
 * 定製化的redis
 * Class Redis
 * @package libs
 */
class Redis extends tpRedis{

    protected static $_instance = null;

    /**
     * 獲取單例redis對象,一般用此方法實例化
     * @return Redis|null
     */
    public static function getInstance()
    {
        if(!is_null(self::$_instance)){
            return self::$_instance;
        }
        self::$_instance = new self();
        return self::$_instance;
    }

    /**
     * 架構函數
     * Redis constructor.
     */
    public function __construct()
    {
        $options = config('cache.redis');
        $options['prefix'] = CacheKeyMap::$prefix;
        parent::__construct($options);
    }

    /**
     * 覆寫,實際的緩存標識以CacheKeyMap來管理
     * @access protected
     * @param  string $name 緩存名
     * @return string
     */
    protected function getCacheKey($name)
    {
        return $name;
    }

    /**
     * redis排重鎖
     * @param $key
     * @param $expires
     * @param int $value
     * @return mixed
     */
    public function redisLock($key, $expires, $value = 1)
    {
        //在key不存在時,添加key並$expires秒過期
        return $this->handler()->set($key, $value, ['nx', 'ex' => $expires]);
    }

    /**
     * 調用緩存類型自己的高級方法
     * @param $method
     * @param $args
     * @return mixed|void
     * @throws \Exception
     */
    public function __call($method,$args){
        if(method_exists($this->handler, $method)){
            return call_user_func_array(array($this->handler,$method), $args);
        }else{
            exception(__CLASS__.':'.$method.'不存在');
            return;
        }
    }
}

服務提供者配置

app/provider.php

// 應用容器綁定定義
return [
    'redis' => 'libs\Redis'
];

使用

$redis = $this->app['redis'];
$redis->hMSet(CacheKeyMap::memberUidHash($uid), ['name' => 'Joe', 'salary' => 2000]);
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章