<?php
/**
 * Created by PhpStorm.
 * Auth: wlb
 * Date: 2020/8/26
 * Time: 17:18
 */
namespace app\common\library\Redis;

use think\Config;

class BaseRedis{

    private $Prefix;
    private $options;
    private $handler;

    public function __construct($options=array()){
        $options = array_merge(array (
            'host'          => Config::get("redis_host") ?: '127.0.0.1',
            'port'          => Config::get("redis_port") ?: 6379,
            'timeout'       => Config::get("data_cache_timeout") ?: false,
            'auth'		=> Config::get("redis_auth") ?:'ehj404f56',   //auth认证
            'persistent'    => false,
        ),$options);

        $this->options =  $options;
        $this->options['expire'] =  isset($options['expire'])?  $options['expire']  :   Config::get("data_cache_time");
        $this->options['prefix'] =  isset($options['prefix'])?  $options['prefix']  :   Config::get("data_cache_prefix");
        $this->options['length'] =  isset($options['length'])?  $options['length']  :   0;
        $this->Prefix = $this->options['prefix'];
        $func = $options['persistent'] ? 'pconnect' : 'connect';
        $this->handler  = new \Redis;
        $options['timeout'] === false ?
            $this->handler->$func($options['host'], $options['port']) :
            $this->handler->$func($options['host'], $options['port'], $options['timeout']);

        //Auth认证
        if($this->options['auth']) {
            $this->handler->auth($this->options['auth']);
        }
    }

    private static $_redis_master_instance;
    static function gi (){
        if(!self::$_redis_master_instance instanceof static){
            self::$_redis_master_instance = new static();
        }
        return self::$_redis_master_instance;
    }

    /**
     * 切换到指定的数据库
     */
    function select($db = 0){
        return $this->handler->select($db);
    }
    function lLen($name){
        return $this->handler->lLen($this->Prefix.$name);
    }

    function rPush($name,$value){
        return $this->handler->rPush($this->Prefix.$name,$value);
    }
    /*
     * 多个参数同时推入list 中
     * */
    function multiRpush($name,$val){
        $name = $this->Prefix.$name;
        array_unshift($val,$name);
        return call_user_func_array([$this->handler,'rPush'],$val);
    }


    function rPop($name){
        return $this->handler->rPop($this->Prefix.$name);
    }
    function lPop($name){
        return $this->handler->lPop($this->Prefix.$name);
    }
    /*
     * $name $key值
     * $time 时间
     * */
    function brPop($name,$time=0){
        return $this->handler->brPop(array($this->Prefix.$name),$time);
    }

    function lPush($name,$value){
        return $this->handler->lPush($this->Prefix.$name,$value);
    }

    function lPushx($name,$value){
        return $this->handler->lPushx($this->Prefix.$name,$value);
    }

    function lRange($name,$start=0,$end=-1){
        return $this->handler->lRange($this->Prefix.$name,$start,$end);
    }
    /*删除redis中的key*/
    function delete($name){
        if(is_array($name)){
            foreach($name as $key=>$val){
                $name[$key] = $this->Prefix.$val;
            }
        }else{
            $name = $this->Prefix.$name;
        }
        return $this->handler->del($name);
    }

    function exists($name){
        return $this->handler->exists($this->Prefix.$name);
    }

    function get($name){
        $value = $this->handler->get($this->Prefix.$name);
        $jsonData  = json_decode( $value, true );
        //检测是否为JSON数据 true 返回JSON解析数组, false返回源数据
        return ($jsonData === NULL) ? $value : $jsonData;
    }

    function set($name,$value){
        if(is_array($value)){
            $value = json_encode($value);
        }
        return $this->handler->set($this->Prefix.$name,$value);
    }

    function incr($name){
        return $this->handler->incr($this->Prefix.$name);
    }
    function incrBy($name,$val){
        return $this->handler->incrBy($this->Prefix.$name,$val);
    }
    function hIncrBy($name,$field,$value=1){
        return $this->handler->hIncrBy($this->Prefix.$name,$field,$value);
    }

    function hDel($name,$field){
        return $this->handler->hDel($this->Prefix.$name,$field);
    }

    function hSet($name,$field,$value){
        return $this->handler->hSet($this->Prefix.$name,$field,$value);
    }

    function hGetAll($name){
        return $this->handler->hGetAll($this->Prefix.$name);
    }

    function hMGet($name,$field){
        return $this->handler->hMGet($this->Prefix.$name,$field);
    }

    function hMset($name,$value){
        return $this->handler->hMset($this->Prefix.$name,$value);
    }

    function setEx($name,$expire,$value){
        return $this->handler->setex($this->Prefix.$name,$expire,$value);
    }

    function setNx($name,$value){
        return $this->handler->setnx($this->Prefix.$name,$value);
    }

    function sAdd($name,$value){
        return $this->handler->sAdd($this->Prefix.$name,$value);
    }

    function multipleSadd(){
        $args = func_get_args();
        $args[0] = $this->Prefix.$args[0];
        return call_user_func_array([$this->handler,'sAdd'],$args);
    }

    function sDiffStore($dstKey,$key1,$key2){
        return $this->handler->sDiffStore($this->Prefix.$dstKey,$this->Prefix.$key1,$this->Prefix.$key2);
    }
    function sPop($name){
        return $this->handler->sPop($this->Prefix.$name);
    }
    /**
     * 将哈希表key中的域field的值设置为 value,当且仅当域 field不存在
     */
    function hSetNx($name,$field,$value){
        return $this->handler->hSetNx($this->Prefix.$name,$field,$value);
    }
    /**
     * 返回集合中的所有成员
     */
    function sMembers($name){
        return $this->handler->sMembers($this->Prefix.$name);
    }
    /**
     * 判断member元素是否集合key的成员。
     */
    function sIsMember($name,$value){
        return $this->handler->sIsMember($this->Prefix.$name,$value);
    }
    /**
     * 返回列表key中,下标为index的元素
     */
    function lIndex($name,$index){
        return $this->handler->lIndex($this->Prefix.$name,$index);
    }
    /**
     * 让列表只保留指定区间内的元素,不在指定区间之内的元素都将被删除
     */
    function lTrim($name,$start,$stop){
        return $this->handler->lTrim($this->Prefix.$name,$start,$stop);
    }
    /**
     * 为key设置生存时间,以时间戳为单位
     */
    function expireAt($name,$timestamp){
        return $this->handler->expireAt($this->Prefix.$name,$timestamp);
    }
    /**
     * 以秒为单位返回给定key的剩余生存时间
     */
    function ttl($name){
        return $this->handler->ttl($this->Prefix.$name);
    }
    /**
     * 返回或保存给定列表,集合,有序集合key中经过排序的元素
     */
    function sort($name,$option=null){
        return $this->handler->sort($this->Prefix.$name,$option);
    }
    /**
     * 清空当前所有key
     */
    /* function flushDB(){
         return $this->handler->flushDB();
     }*/
    /**
     * 标记一个事务块的开始
     */
    function multi(){
        return $this->handler->multi();
    }
    /**
     * 执行所有事务块内的命令
     */
    function exec(){
        return $this->handler->exec();
    }
    /**
     * 取消事务，放弃执行事务块内的所有命令。
     */
    function discard(){
        $this->handler->discard();
    }

    function keys($pattern){
        return $this->handler->keys($pattern);
    }

    /**
     * List操作函数 根据参数 count 的值，移除列表中与参数 value 相等的元素。
     * count > 0 : 从表头开始向表尾搜索，移除与 value 相等的元素，数量为 count 。
     * count < 0 : 从表尾开始向表头搜索，移除与 value 相等的元素，数量为 count 的绝对值。
     * count = 0 : 移除表中所有与 value 相等的值。
     */
    function lRem($name,$value,$count=0){
        return $this->handler->lRem($this->Prefix.$name,$value,$count);
    }
    /**
     * List操作函数   将值 value 插入到列表 key 当中，位于值 pivot 之前或之后。
     * @param $pivot list中存在的值
     * @param $position BEFORE OR AFTER
     * @param $value 需要插入的值
     */
    function lInsert($name,$value,$pivot,$position){
        return $this->handler->lInsert($this->Prefix.$name,$position,$pivot,$value);
    }
    /**
     * Hash操作函数   查看哈希表 key 中，给定域 field 是否存在。
     * @param $name $key值
     * @param $field 字段值
     * @return true or false
     */
    function hExists($name,$field){
        return $this->handler->hExists($this->Prefix.$name,$field);
    }
    /**
     * List操作函数 将列表 key 下标为 index 的元素的值设置为 value 。
     * @param $name $key值
     * @param $index int 索引值
     * @return true or false
     */
    function lSet($name,$index,$value){
        return $this->handler->lSet($this->Prefix.$name,$index,$value);
    }
    /**
     *有序操作函数 添加操作
     * @param $name $key值
     * @param $sort int 排序值
     * @param $value int 值
     * @return array|bool
     */
    function zAdd($name,$sort=0,$value){
        if(!$value){
            return false;
        }
        return $this->handler->zAdd($this->Prefix.$name,$sort,$value);
    }
    /**
     *有序SET操作函数 返回有序集 key 中，指定区间内的成员。
     * @param $name $key值
     * @param $start int 开始位置
     * @param $end  int 结束位置
     * @param $withscores
     * @return array|bool
     */
    function zRevRange($name, $start, $end, $withscores = null){
        return $this->handler->zRevRange($this->Prefix.$name,$start,$end,$withscores);
    }
    /**
     *有序SET操作函数 返回有序集 key 中的成员数量
     * @param $name $key值
     * @return int
     */
    function zCard($name){
        return $this->handler->zCard($this->Prefix.$name);
    }

    function zRank($name,$member){
        return $this->handler->zRank($this->Prefix.$name,$member);
    }

    function zRevRank($name,$member){
        return $this->handler->zRevRank($this->Prefix.$name,$member);
    }
    /**
     *有序SET操作函数 移除有序集 key 中的一个或多个成员，
     * @param $name $key值
     * @param $value int 需要删除的值
     * @return int   删除的数量
     */
    function zRem($name,$value){
        return $this->handler->zRem($this->Prefix.$name,$value);
    }
    /**
     *有序SET操作函数 为集合中的某个元素 增量+ $value
     * @param $name $key值
     * @param $value int 需要增加的值
     * @param $member string  需要被增加的值
     * @return int   删除的数量
     */
    function zIncrBy($name,$member,$value=1){
        return $this->handler->zIncrBy($this->Prefix.$name,$value,$member);
    }

    function zScore($name,$field){
        return $this->handler->zScore($this->Prefix.$name,$field);
    }

    function zRange($name,$start,$end,$withscores=false){
        return $this->handler->zRange($this->Prefix.$name,$start,$end,$withscores);
    }

    function sRandMember($name,$count){
        return $this->handler->sRandMember($this->Prefix.$name,$count);
    }
    /*
     * 集合长度
     * */
    function sCard($name){
        return $this->handler->sCard($this->Prefix.$name);
    }

    /*
     * 获取单个hash值
     * */
    function hGet($name,$field){
        return $this->handler->hGet($this->Prefix.$name,$field);
    }

    function hLen($name){
        return $this->handler->hLen($this->Prefix.$name);
    }

    function zRangeByScore($name, $start, $end, $options = array() ) {
        return $this->handler->zRangeByScore($this->Prefix.$name,$start,$end,$options);
    }
    /*
  * 删除集合中的元素
  * */
    function sRem($name,$value){
        return $this->handler->sRem($this->Prefix.$name,$value);
    }
    /*
   * 删除集合中的元素 根据score的范围
   * */
    function zRemRangeByScore($name,$start,$end){
        return $this->handler->zRemRangeByScore($this->Prefix.$name,$start,$end);
    }
    function scan($iterator, $pattern = '', $count = 0){
        return $this->handler->scan($iterator, $pattern, $count);
    }
    function evaluate($script, $args = array(), $numKeys = 0){
        return $this->handler->evaluate($script, $args, $numKeys);
    }

    /**
     * 添加指定元素到 HyperLogLog 中
     * @param $name
     * @param $value
     * @return mixed
     */
    function pfAdd($name, $value) {
        return $this->handler->pfAdd($this->Prefix.$name, $value);
    }

    /**
     * 获取 HyperLogLog 长度
     * @param $name
     * @return mixed
     */
    function pfCount($name){
        return $this->handler->pfCount($this->Prefix.$name);
    }

    function getHashAll($name){
        return $this->handler->hGetAll($this->Prefix.$name);
    }
}