RedisPool.php 5.8 KB
<?php

namespace Lib;

/**
 * redis 链接池 swoole内置了链接池,自能在协程中使用,所以单独写出来
 * @author:dc
 * @time 2023/2/10 17:04
 * Class RedisPool
 */
class RedisPool {

    /**
     * @var \Lib\RedisPool[]
     */
    static $instance = [];

    /**
     * @var \Redis
     */
    private $client;


    public function __construct()
    {
        $this->conn();
    }

    /**
     * 链接
     * @author:dc
     * @time 2023/4/12 15:10
     */
    private function conn(){
        $this->client = new \Redis();

        $this->client->connect(REDIS_HOST,REDIS_PORT,1);
        // 密码
        REDIS_PASSWORD && $this->client->auth(REDIS_PASSWORD);
        // 用库4
        $this->client->select(REDIS_DB);
    }



    /**
     * @param $key
     * @return bool|int
     * @author:dc
     * @time 2023/2/10 18:06
     */
    public function has($key)
    {
        return $this->getClient()->exists($key);
    }


    /**
     * @param $key
     * @param null $default
     * @return mixed|null
     * @author:dc
     * @time 2023/2/10 18:04
     */
    public function get($key, $default=null)
    {
        $data = $this->getClient()->get($key);
        if($data === null){
            return $default;
        }
        return $this->unserialize($data);
    }

    /**
     * @param $key
     * @param $val
     * @param null $ttl
     * @return bool
     * @author:dc
     * @time 2023/2/10 18:02
     */
    public function set($key,$val,$ttl=null) {
        return $this->getClient()->set($key,$this->serialize($val),$ttl);
    }


    /**
     * 如果有key返回false,没有则新增
     * @param $key
     * @param $val
     * @param null $ttl
     * @return mixed
     * @author:dc
     * @time 2023/2/10 17:53
     */
    public function add($key,$val,$ttl=null):mixed {
        return $this->getClient()->eval(
            "return redis.call('exists',KEYS[1])<1 and redis.call('setex',KEYS[1],ARGV[2],ARGV[1])",
            [$key, $this->serialize($val), $ttl],
            1
        );
    }

    /**
     * @param $key
     * @param $value
     * @return false|int
     * @author:dc
     * @time 2023/2/13 9:07
     */
    public function lPush($key,$value){
        return $this->getClient()->lPush($key,$this->serialize($value));
    }

    /**
     * @param $key
     * @param $value
     * @return false|int
     * @author:dc
     * @time 2023/2/13 9:07
     */
    public function rPush($key,$value){
        return $this->getClient()->rPush($key,$this->serialize($value));
    }

    /**
     * @param $key
     * @return bool|mixed
     * @author:dc
     * @time 2023/2/13 9:08
     */
    public function lPop($key){
        return $this->unserialize($this->getClient()->lPop($key));
    }

    /**
     * @param $key
     * @return mixed|string
     * @author:dc
     * @time 2023/2/13 9:09
     */
    public function rPop($key){
        return $this->unserialize($this->getClient()->rPop($key));
    }

    /**
     * 自增
     * @param $key
     * @param null $ttl
     * @return int
     * @author:dc
     * @time 2023/2/17 15:29
     */
    public function incr($key, $ttl = null){
        if($ttl){
            return $this->getClient()->eval(
                "local x = redis.call('incr',KEYS[1]);redis.call('expire',KEYS[1],ARGV[1]);return x",
                [$key, $ttl],
                1
            );
        }
        return $this->getClient()->incr($key);
    }

    /**
     * 自减
     * @param $key
     * @param null $ttl
     * @return int
     * @author:dc
     * @time 2023/3/16 11:19
     */
    public function decr($key,$ttl = null){
        if($ttl){
            return $this->getClient()->eval(
                "local x = redis.call('decr',KEYS[1]);redis.call('expire',KEYS[1],ARGV[1]);return x",
                [$key, $ttl],
                1
            );
        }
        return $this->getClient()->decr($key);
    }


    /**
     * 删除
     * @param $key
     * @return int
     * @author:dc
     * @time 2023/2/14 14:04
     */
    public function delete($key):int {
        return $this->getClient()->del($key);
    }

    /**
     * 获取值并删除
     * @param $key
     * @return mixed
     * @author:dc
     * @time 2023/3/16 11:36
     */
    public function getDel($key){
        return $this->getClient()->eval(
            "local x = redis.call('get',KEYS[1]);if x then redis.call('del',KEYS[1]) end return x",
            [$key],
            1
        );
    }


    /**
     * @param $val
     * @return string
     * @author:dc
     * @time 2023/2/10 17:57
     */
    private function serialize($val){
        return $val ? serialize($val) : '';
    }

    /**
     * @param $val
     * @return mixed
     * @author:dc
     * @time 2023/2/10 17:58
     */
    private function unserialize($val){
        return $val ? unserialize($val) : '';
    }

    /**
     * @return \Redis
     * @author:dc
     * @time 2023/4/12 15:11
     */
    public function getClient(){
        try {
            $this->client->ping();
        }catch (\RedisException $e){
            $this->conn();
        }
        return $this->client;
    }



    public function __destruct()
    {
       $this->close();
    }


    /**
     * @param $cid
     * @return \Lib\RedisPool
     * @author:dc
     * @time 2023/2/13 9:38
     */
    public static function instance($cid){
        if(empty(static::$instance[$cid])){
            static::$instance[$cid] = new \Lib\RedisPool();
        }

        return static::$instance[$cid];
    }


    /**
     * 关闭
     * @author:dc
     * @time 2023/3/16 13:42
     */
    public function close(){
        // TODO: Implement __destruct() method.
        try {
            $this->client->ping();
            $this->client->close();
        }catch (\RedisException $e){}

        $this->client = null;
    }







}