Sfoglia il codice sorgente

再添加一个 redis 客户端,业务逻辑使用和 cache 分开

joe 4 anni fa
parent
commit
f6e0d9b03b

+ 11 - 0
config/redis.php

@@ -0,0 +1,11 @@
+<?php
+
+return [
+    'driver'     => 'redis',
+    'host'       => '127.0.0.1',
+    'port'       => 6379,
+    'password'   => '123456',
+    'select'     => 2,
+    'timeout'    => 0,
+    'persistent' => false,
+];

+ 11 - 1
tw/redis/Base.php

@@ -3,10 +3,20 @@
 namespace tw\redis;
 
 
+/**
+ *  redis 操作基类
+ * 
+ *  Base               HashTrait         StringTrait         HsetTrait
+ *   |
+ *   |
+ * DerivedClass (use a Trait)
+ * 
+ * DerivedClass 属于一个类型的键
+ */
 abstract class Base
 {
     /**
-     * 需函数,返回键
+     * 函数,返回键
      * @param integer|string $word: 组成键的关键部分
      * @return string
      */ 

+ 0 - 41
tw/redis/HashTrait.php

@@ -1,41 +0,0 @@
-<?php
-namespace tw\redis;
-
-use crmeb\utils\Redis;
-
-trait HashTrait 
-{
-    public function get($word, $attr) : string
-    {
-        return Redis::hGet($this->key($word), $attr);
-    }
-
-    public function gets($word, $attrs) : array
-    {
-        return Redis::hMGet($this->key($word), $attrs);
-    }
-
-    public function set($word, $attr, $value) : bool
-    {
-        return Redis::hSet($this->key($word), $attr, $value);
-    }
-
-    public function sets($word, $attrs) : bool
-    {
-        return Redis::hMSet($this->key($word), $attrs);
-    }
-
-    public function dels($word, $attrs) : int
-    {
-        if (is_string($attrs)) {
-            return Redis::hDel($this->key($word), $attrs);
-        }else if (is_array($attrs)) {
-            return Redis::hDel($this->key($word), ...$attrs);
-        }
-    }
-
-    public function getAll($word) : array
-    {
-        return Redis::hGetAll($this->key($word));
-    }
-}

+ 1 - 0
tw/redis/ProductCategoryRds.php

@@ -2,6 +2,7 @@
 
 namespace tw\redis;
 
+use tw\redis\traits\HashTrait;
 
 class ProductCategoryRds extends Base
 {

+ 2 - 0
tw/redis/ProductRds.php

@@ -2,6 +2,8 @@
 
 namespace tw\redis;
 
+use tw\redis\traits\HashTrait;
+
 class ProductRds extends Base 
 {
     use HashTrait;

+ 51 - 0
tw/redis/TwRedis.php

@@ -0,0 +1,51 @@
+<?php
+namespace tw\redis;
+
+use think\facade\Config;
+
+/**
+ * 另一个 Redis 客户端,另一个是 Cache 使用
+ */
+class TwRedis {
+
+    protected static $inst;
+
+    protected $handle;
+
+    protected function __construct($options)
+    {
+        if (extension_loaded('redis')) {
+            $this->handle = new \Redis;
+
+            if ($options['persistent']) {
+                $this->handle->pconnect($options['host'], $options['port'], $options['timeout'], 'tw_persistent_id' . $options['select']);
+            } else {
+                $this->handle->connect($options['host'], $options['port'], $options['timeout']);
+            }
+            if ('' != $options['password']) {
+                $this->handle->auth($options['password']);
+            }
+            if (0 != $options['select']) {
+                $this->handle->select($options['select']);
+            }
+            
+        } else {
+            throw new \BadFunctionCallException('not support: redis');
+        }
+    }
+
+    public static function instance()
+    {
+        if ( is_null(self::$inst) ) {
+            $options = Config::get('redis', []);
+            print_r($options);
+            self::$inst = new static($options);
+        }
+        return self::$inst;
+    }
+
+    public static function __callStatic($name, $arguments)
+    {
+        return self::instance()->handle->{$name}(...$arguments);
+    }
+}

+ 1 - 1
tw/redis/UserRds.php

@@ -2,7 +2,7 @@
 
 namespace tw\redis;
 
-use crmeb\utils\Redis;
+use tw\redis\traits\HashTrait;
 
 class UserRds extends Base
 {

+ 1 - 0
tw/redis/test/UserRdsTest.php

@@ -0,0 +1 @@
+<?php

+ 91 - 0
tw/redis/traits/HashTrait.php

@@ -0,0 +1,91 @@
+<?php
+namespace tw\redis\traits;
+
+use tw\redis\TwRedis;
+
+/**
+ * 支持 redis hash key 操作的函数, 必须 use 到 Base 的子类中, 因为内部调用了 Base 的虚函数
+ * 
+ */
+trait HashTrait 
+{
+    /**
+     * 获取 hash attr
+     * 
+     * @param int|string $word
+     * @param string $attr
+     * @return string
+     */
+    public function get($word, string $attr) : string
+    {
+        return TwRedis::hGet($this->key($word), $attr);
+    }
+
+    public function gets($word, array $attrs) : array
+    {
+        return TwRedis::hMGet($this->key($word), $attrs);
+    }
+
+    /**
+     * set hash attr
+     */
+    public function set($word, string $attr, $value) : bool
+    {
+        return TwRedis::hSet($this->key($word), $attr, $value);
+    }
+
+    public function sets($word, array $attrs) : bool
+    {
+        return TwRedis::hMSet($this->key($word), $attrs);
+    }
+
+    /**
+     * setup hash value if the attr not exists
+     */
+    public function hsetnx($word, $attr, $val) : bool
+    {
+        return TwRedis::hSetNx($this->key($word), $attr, $val);
+    }
+    
+    /**
+     * hash 的 attr 是否存在
+     */
+    public function hexists($word, string $attr) : bool
+    {
+        return TwRedis::hExists($this->key($word), $attr);
+    }
+
+    public function hincr_by($word, string $attr, int $step) : int
+    {
+        return TwRedis::hIncrBy($this->key($word), $attr, $step);
+    }
+
+    public function hincr_by_float($word, string $attr, float $f) : float
+    {
+        return TwRedis::hIncrByFloat($this->key($word), $attr, $f);
+    }
+
+    public function hkeys($word) : array
+    {
+        return TwRedis::hKeys($this->key($word));
+    }
+
+    public function hvals($word) : array
+    {
+        return TwRedis::hVals($this->key($word));
+    }
+
+    public function dels($word, $attrs) : int
+    {
+        if (is_string($attrs)) {
+            return TwRedis::hDel($this->key($word), $attrs);
+        } else if (is_array($attrs)) {
+            return TwRedis::hDel($this->key($word), ...$attrs);
+        }
+    }
+
+    public function getAll($word) : array
+    {
+        return TwRedis::hGetAll($this->key($word));
+    }
+}

+ 41 - 0
tw/redis/traits/KeyTrait.php

@@ -0,0 +1,41 @@
+<?php
+namespace tw\redis\traits;
+
+use tw\redis\TwRedis;
+
+trait KeyTrait
+{
+    public function keys(string $pattern) : array
+    {
+        return TwRedis::keys($pattern);
+    }
+
+    public function expire($word, int $secs) : bool
+    {
+        return TwRedis::expire($this->key($word), $secs);
+    }
+
+    /**
+     * 设置超时时间戳,到达该时间戳后,key 失效
+     */
+    public function expire_at($word, int $ts) : bool
+    {
+        return TwRedis::expireAt($this->key($word), $ts);
+    }
+
+    public function del($word) : int
+    {
+        return TwRedis::del($this->key($word));
+    }
+
+    public function type($word)
+    {
+        return TwRedis::type($this->key($word));
+    }
+
+    public function exists($word) : int
+    {
+        return TwRedis::exists($this->key($word));
+    }
+
+}

+ 117 - 0
tw/redis/traits/ListTrait.php

@@ -0,0 +1,117 @@
+<?php
+namespace tw\redis\traits;
+
+use tw\redis\TwRedis;
+
+trait ListTrait
+{
+    /**
+     * 头部插入一个或多个元素
+     * 
+     * @param int|string|array $vals: 待插入元素
+     * @return int|bool: List 长度|false, 当 $word 存在并且构成的 key 不是 List 类型时失败
+     */
+    public function lpush($word, $vals)
+    {
+        if (is_array($vals)) {
+            return TwRedis::lPush($this->key($word), ...$vals);
+        } else {
+            return TwRedis::lPush($this->key($word), $vals);
+        }
+    }
+
+    /**
+     * 从尾部追加元素
+     * 
+     * @param string|int|array $vals
+     * @return int|bool: key 存在并且类型不为 List 时返回 false
+     */
+    public function rpush($word, $vals)
+    {
+        if (is_array($vals)) {
+            return TwRedis::rPush($this->key($word), ...$vals);
+        } else {
+            return TwRedis::rPush($this->key($word), $vals);
+        }
+    }
+
+    /**
+     * 移除并返回 List 第一个元素
+     * 
+     * @param int|string $word: key 关键字
+     * @return bool|string: 空 List 返回 false, 否则返回值
+     */
+    public function lpop($word)
+    {
+        return TwRedis::lPop($this->key($word));
+    }
+
+    /**
+     * 返回并删除最后一个元素
+     * 
+     * @return string|bool: 空 List 返回 false
+     */
+    public function rpop($word)
+    {
+        return TwRedis::rPop($this->key($word));
+    }
+
+    public function lrange($word, $start, $stop) : array
+    {
+        return TwRedis::lRange($this->key($word), $start, $stop);
+    }
+
+    /**
+     * 删除指定元素(注意这个函数复杂度为O(n))
+     * 
+     * @param string $val: 元素值
+     * @param int $num: 删除个数,0表示所有,负值表示从尾部开始删
+     * @return int|bool: 删除个数|false 
+     */
+    public function lrem($word, $val, $num)
+    {
+        return TwRedis::lRem($this->key($word), $val, $num);
+    }
+
+    /**
+     * 从头部删除指定个数的元素
+     * 
+     * @param int $start
+     * @param int $stop
+     * @return array|bool: 已删元素|失败 
+     */
+    public function ltrim($word, $start, $stop)
+    {
+        return TwRedis::lTrim($this->key($word), $start, $stop);
+    }
+
+    /**
+     * 插入 $val 到 $pivot 后
+     * 
+     * @return int: -1 表示 $pivot 未找到
+     */
+    public function linsert_after($word, $pivot, $val) : int
+    {
+        return TwRedis::lInsert($this->key($word), \Redis::AFTER, $pivot, $val);
+    }
+
+    /**
+     * 插入 $val 到 $pivot 前
+     * 
+     * @return int: -1 表示 $pivot 未找到
+     */
+    public function linsert_before($word, $pivot, $val) : int
+    {
+        return TwRedis::lInsert($this->key($word), \Redis::BEFORE, $pivot, $val);
+    }
+
+    /**
+     * 求长度
+     * 
+     * @return int|bool: 长度|失败(当 key 不是 List)
+     */
+    public function llen($word)
+    {
+        return TwRedis::lLen($this->key($word));
+    }
+}

+ 121 - 0
tw/redis/traits/SortedSetTrait.php

@@ -0,0 +1,121 @@
+<?php
+namespace tw\redis\traits;
+
+use tw\redis\TwRedis;
+
+trait SortedSetTrait {
+    
+    /**
+     * 添加/更新一个元素
+     * 
+     * @param string $val
+     * @param float $score
+     * @return int 0|1 1代表新增
+     */
+    public function zadd($word, $val, $score) : int
+    {
+        return TwRedis::zAdd($this->key($word), $score, $val);
+    }
+
+    /**
+     * 删除 1 个或多个元素
+     */
+    public function zrem($word, $members) : int
+    {
+        if (is_array($members)) {
+            return TwRedis::zRem($this->key($word), ...$members);
+        } else {
+            return TwRedis::zRem($this->key($word), $members);
+        }
+        
+    }
+
+    /**
+     * 求一个元素的分数
+     * 
+     * @param string $member
+     * @return float|bool 分数|失败
+     */
+    public function zscore($word, $member)
+    {
+        return TwRedis::zScore($this->key($word), $member);
+    }
+
+    /**
+     * 求一个元素的排名
+     * 
+     * @param string $member
+     * @return float 名次
+     */
+    public function zrank($word, $member) : float
+    {
+        return TwRedis::zRank($this->key($word), $member);
+    }
+
+    /**
+     * 求 zset 的基数
+     */
+    public function zcard($word) : int
+    {
+        return TwRedis::zCard($this->key($word));
+    }
+
+    /**
+     * 求分数在 $start,$end 之间的元素个数
+     * 
+     * @param float|string $start,$end: 也可以包括 +inf -inf 表示正负无穷
+     * @return 
+     */
+    public function zcount($word, $start, $end) : int
+    {
+        return TwRedis::zCount($this->key($word), $start, $end);
+    }
+
+    /**
+     * 增加指定元素的分数
+     */
+    public function zincr_by($word, $member, $by) : float
+    {
+        return TwRedis::zIncrBy($this->key($word), $by, $member);
+    }
+
+    /**
+     * 弹出分数最大的几个
+     */
+    public function zpop_max($word, $num) : array
+    {
+        return TwRedis::zPopMax($this->key($word), $num);
+    }
+
+    /**
+     * 弹出分数最小的几个
+     */
+    public function zpop_min($word, $num) : array
+    {
+        return TwRedis::zPopMin($this->key($word), $num);
+    }
+
+    /**
+     * 返回分数在 $start, $end 之间的子集合
+     * @param float|string $start, $end: 范围 +inf, -inf 也可以
+     * @param array $options: 例子:
+     * ['withscores' => TRUE]
+     * ['limit' => [1, 1]]
+     * ['withscores' => TRUE, 'limit' => [1, 1]]
+     * @return
+     */
+    public function zrange_by_score($word, $start, $end, $options) : array
+    {
+        return TwRedis::zRangeByScore($this->key($word), $start, $end, $options);
+    }
+
+    public function zrem_range_by_rank($word, $start, $end)
+    {
+        return TwRedis::zRemRangeByRank($this->key($word), $start, $end);
+    }
+
+    public function zrem_range_by_score($word, $start, $end)
+    {
+        return TwRedis::zRemRangeByScore($this->key($word), $start, $end);
+    }
+}

+ 53 - 0
tw/redis/traits/StringTrait.php

@@ -0,0 +1,53 @@
+<?php
+namespace tw\redis\traits;
+
+use tw\redis\TwRedis;
+
+
+trait StringTrait
+{
+    public function get($word)
+    {
+        return TwRedis::get($this->key($word));
+    }
+
+    public function set($word, $val)
+    {
+        return TwRedis::set($this->key($word), $val);
+    }
+
+    /**
+     * 设置 string 同时设置 TTL
+     * 
+     * @param int|string $word: 关键字
+     * @param int|float|string $val: 值
+     * @param int $expire: TTL in millisecond  1s = 1000 millisecond
+     */
+    public function set_with_expire($word, $val, $expire)
+    {
+        return TwRedis::setEx($this->key($word), $expire, $val);
+    }
+
+    /**
+     * key 不存在时设置
+     */
+    public function setnx($word, $val)
+    {
+        return TwRedis::setNx($this->key($word), $val);
+    }
+
+    public function incr_by($word, $step)
+    {
+        return TwRedis::incrBy($this->key($word), $step);
+    }
+
+    public function incr_by_float($word, $f)
+    {
+        return TwRedis::incrByFloat($this->key($word), $f);
+    }
+
+    public function decr_by($word, $step)
+    {
+        return TwRedis::decrBy($this->key($word), $step);
+    }
+}

+ 2 - 0
tw/services/Alipay.php

@@ -0,0 +1,2 @@
+<?php
+namespace tw\services;

+ 2 - 0
tw/services/WechatPay.php

@@ -0,0 +1,2 @@
+<?php
+namespace tw\services;