RedisDriver.php 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. <?php
  2. /**
  3. * The cache library of zentaopms.
  4. *
  5. * @copyright Copyright 2009-2024 禅道软件(青岛)有限公司(ZenTao Software (Qingdao) Co., Ltd. www.zentao.net)
  6. * @license ZPL(https://zpl.pub/page/zplv12.html) or AGPL(https://www.gnu.org/licenses/agpl-3.0.en.html)
  7. * @author dingguodong <dingguodong@easycorp.ltd>
  8. * @package cache
  9. * @link https://www.zentao.net
  10. */
  11. namespace ZenTao\Cache\Driver;
  12. use ZenTao\Cache\SimpleCache\CacheInterface;
  13. use ZenTao\Cache\SimpleCache\InvalidArgumentException;
  14. class RedisDriver implements CacheInterface
  15. {
  16. /**
  17. * 缓存命名空间,用来区分不同的缓存。
  18. * The cache namespace, used to distinguish different caches.
  19. *
  20. * @var string
  21. */
  22. private $namespace;
  23. /**
  24. * 缓存过期时间,单位为秒。
  25. * The cache expiration time, in seconds.
  26. *
  27. * @var int
  28. */
  29. private $defaultLifetime;
  30. /**
  31. * 缓存服务范围。private 独享|public 共享。
  32. * The cache scope.
  33. *
  34. * @access private
  35. * @var string
  36. */
  37. private $scope;
  38. /**
  39. * 缓存键连接符。
  40. * Cache key connector.
  41. *
  42. * @access private
  43. * @var string
  44. */
  45. private $connector;
  46. public function __construct($namespace = '', $defaultLifetime = 0, $scope = '', $connector = '', $setting = null)
  47. {
  48. $this->namespace = $namespace;
  49. $this->defaultLifetime = $defaultLifetime;
  50. $this->scope = $scope;
  51. $this->connector = $connector;
  52. $this->connectRedis($setting);
  53. }
  54. /**
  55. * 连接 Redis 服务器。
  56. * Connect to the Redis server.
  57. *
  58. * @param object $setting
  59. * @access private
  60. * @return object
  61. */
  62. private function connectRedis($setting)
  63. {
  64. global $config;
  65. try
  66. {
  67. $this->redis = \helper::connectRedis($setting);
  68. $this->redis->setOption(\Redis::OPT_SERIALIZER, $this->getSerializer($setting->serializer));
  69. $this->redis->select($setting->database);
  70. }
  71. catch(Exception $e)
  72. {
  73. \helper::end($e->getMessage());
  74. }
  75. }
  76. /**
  77. * 设置序列化器。
  78. * Set the serializer.
  79. *
  80. * @param string $serializer
  81. * @access private
  82. * @return void
  83. */
  84. private function getSerializer($serializer)
  85. {
  86. if($serializer == 'igbinary') return \Redis::SERIALIZER_IGBINARY;
  87. if($serializer == 'php') return \Redis::SERIALIZER_PHP;
  88. if($serializer == 'msgpack') return \Redis::SERIALIZER_MSGPACK;
  89. if($serializer == 'json') return \Redis::SERIALIZER_JSON;
  90. }
  91. /**
  92. * Get the value related to the specified key.
  93. *
  94. * @link https://github.com/phpredis/phpredis?tab=readme-ov-file#get
  95. * @param mixed $key
  96. * @param mixed $default
  97. * @return mixed
  98. */
  99. public function get($key, $default = null)
  100. {
  101. $value = $this->redis->get($key);
  102. return $value ? $value : $default;
  103. }
  104. /**
  105. * Set the string value in argument as value of the key.
  106. *
  107. * @param mixed $key
  108. * @param mixed $value
  109. * @param mixed $ttl
  110. * @return void
  111. */
  112. public function set($key, $value, $ttl = null)
  113. {
  114. $ttl = (int)($ttl ?: $this->defaultLifetime);
  115. return $this->redis->set($key, $value, $ttl ?: null);
  116. }
  117. /**
  118. * Remove specified keys.
  119. *
  120. * @link https://github.com/phpredis/phpredis?tab=readme-ov-file#del-delete-unlink
  121. * @param mixed $key
  122. * @return int
  123. */
  124. public function delete($key)
  125. {
  126. return $this->redis->del($key);
  127. }
  128. /**
  129. * Remove all keys from the current database.
  130. *
  131. * @link https://github.com/phpredis/phpredis?tab=readme-ov-file#flushdb
  132. * @return bool
  133. */
  134. public function clear()
  135. {
  136. if($this->scope == 'private') return $this->redis->flushDB();
  137. /* With Redis::SCAN_RETRY enabled */
  138. $this->redis->setOption(\Redis::OPT_SCAN, \Redis::SCAN_RETRY);
  139. $it = null;
  140. $keys = [];
  141. while($cachedKeys = $this->redis->scan($it, $this->namespace . $this->connector . '*'))
  142. {
  143. if(!is_array($cachedKeys)) break;
  144. $keys = array_merge($keys, $cachedKeys);
  145. }
  146. return $this->deleteMultiple($keys);
  147. }
  148. /**
  149. * Get the values of all the specified keys.
  150. *
  151. * @param array $keys
  152. * @param mixed $default
  153. * @return array
  154. */
  155. public function getMultiple($keys, $default = null)
  156. {
  157. $result = $this->redis->mget($keys);
  158. if(!is_array($result)) return [];
  159. return array_filter(array_combine($keys, $result));
  160. }
  161. /**
  162. * Sets multiple key-value pairs in one atomic command.
  163. *
  164. * @link https://github.com/phpredis/phpredis?tab=readme-ov-file#mset-msetnx
  165. * @param mixed $values
  166. * @param mixed $ttl
  167. * @return bool
  168. */
  169. public function setMultiple($values, $ttl = null)
  170. {
  171. $ttl = (int)($ttl ?: $this->defaultLifetime);
  172. if(!$ttl) return $this->redis->mset($values);
  173. foreach($values as $key => $value) $this->redis->set($key, $value, $ttl);
  174. }
  175. /**
  176. * Delete the multiple keys.
  177. *
  178. * @param array $keys
  179. * @return bool
  180. */
  181. public function deleteMultiple($keys)
  182. {
  183. $result = $this->redis->del($keys);
  184. return $result === count($keys);
  185. }
  186. /**
  187. * Verify if the specified key exists.
  188. *
  189. * @link https://github.com/phpredis/phpredis?tab=readme-ov-file#exists
  190. * @param mixed $key
  191. * @return bool
  192. */
  193. public function has($key)
  194. {
  195. return (bool) $this->redis->exists($key);
  196. }
  197. /**
  198. * 关闭 Redis 连接。
  199. * Close the Redis connection.
  200. *
  201. * @access public
  202. * @return bool
  203. */
  204. public function close()
  205. {
  206. return $this->redis->close();
  207. }
  208. /**
  209. * 获取内存使用情况。
  210. * Get memory usage.
  211. *
  212. * @param string $type
  213. * @return string
  214. */
  215. public function memory($type)
  216. {
  217. $info = $this->redis->info();
  218. if($type == 'total') return $info['total_system_memory_human'];
  219. if($type == 'free') return \helper::formatKB($info['total_system_memory'] - $info['used_memory']);
  220. if($type == 'used') return $info['used_memory_human'];
  221. if($type == 'rate') return round(($info['used_memory'] / $info['total_system_memory']) * 100, 2);
  222. return '';
  223. }
  224. }