<?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; /** * @var */ private $cid; /** * 最后执行的时间 * @var int */ public $lastTimer; public function __construct($cid) { $this->cid = $cid; $this->conn(); } /** * 链接 * @author:dc * @time 2023/4/12 15:10 */ private function conn(){ $this->lastTimer = time(); $this->client = new \Redis(); $this->client->pconnect(REDIS_HOST,REDIS_PORT,2); // 密码 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 * @return false|mixed|string * @author:dc * @time 2023/4/12 16:51 */ public function getOriginData($key){ return $this->getClient()->get($key); } /** * @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( " if redis.call('exists',KEYS[1]) == 0 then local x = redis.call('incr',KEYS[1]) if x then redis.call('expire',KEYS[1],ARGV[1]) end return x else return redis.call('incr',KEYS[1]) end", [$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( " if redis.call('exists',KEYS[1]) == 0 then local x = redis.call('decr',KEYS[1]) if x then redis.call('expire',KEYS[1],ARGV[1]) end return x else return redis.call('decr',KEYS[1]) end", [$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 { if(!$this->client->ping()){ $this->conn(); } }catch (\Throwable $e){ $this->conn(); } $this->lastTimer = time(); 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($cid); } 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 (\Throwable $e){ } unset(static::$instance[$this->cid]); $this->client = null; } }