Redis.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | ThinkPHP [ WE CAN DO IT JUST THINK ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
  6. // +----------------------------------------------------------------------
  7. // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
  8. // +----------------------------------------------------------------------
  9. // | Author: liu21st <liu21st@gmail.com>
  10. // +----------------------------------------------------------------------
  11. namespace think\cache\driver;
  12. use think\cache\Driver;
  13. /**
  14. * Redis缓存驱动,适合单机部署、有前端代理实现高可用的场景,性能最好
  15. * 有需要在业务层实现读写分离、或者使用RedisCluster的需求,请使用Redisd驱动
  16. *
  17. * 要求安装phpredis扩展:https://github.com/nicolasff/phpredis
  18. *
  19. * @author 尘缘 <130775@qq.com>
  20. * Modified by wuyonghong BEGIN 2019/02/19 ISSUES Redis添加有序队列支持
  21. */
  22. class Redis extends Driver {
  23. protected $options
  24. = [
  25. 'host' => '127.0.0.1',
  26. 'port' => 6379,
  27. 'password' => '',
  28. 'select' => 0,
  29. 'timeout' => 0,
  30. 'expire' => 0,
  31. 'persistent' => false,
  32. 'prefix' => '',
  33. ];
  34. /**
  35. * 构造函数
  36. *
  37. * @param array $options 缓存参数
  38. *
  39. * @access public
  40. */
  41. public function __construct($options = []) {
  42. if (!extension_loaded('redis')) {
  43. throw new \BadFunctionCallException('not support: redis');
  44. }
  45. if (!empty($options)) {
  46. $this->options = array_merge($this->options, $options);
  47. }
  48. $this->handler = new \Redis;
  49. if ($this->options['persistent']) {
  50. $this->handler->pconnect(
  51. $this->options['host'], $this->options['port'], $this->options['timeout'],
  52. 'persistent_id_'.$this->options['select']
  53. );
  54. } else {
  55. $this->handler->connect($this->options['host'], $this->options['port'], $this->options['timeout']);
  56. }
  57. if ('' != $this->options['password']) {
  58. $this->handler->auth($this->options['password']);
  59. }
  60. if (0 != $this->options['select']) {
  61. $this->handler->select($this->options['select']);
  62. }
  63. }
  64. /**
  65. * 判断缓存
  66. *
  67. * @access public
  68. *
  69. * @param string $name 缓存变量名
  70. *
  71. * @return bool
  72. */
  73. public function has($name) {
  74. return $this->handler->exists($this->getCacheKey($name));
  75. }
  76. /**
  77. * 读取缓存
  78. *
  79. * @access public
  80. *
  81. * @param string $name 缓存变量名
  82. * @param mixed $default 默认值
  83. *
  84. * @return mixed
  85. */
  86. public function get($name, $default = false) {
  87. $value = $this->handler->get($this->getCacheKey($name));
  88. if (is_null($value) || false === $value) {
  89. return $default;
  90. }
  91. try {
  92. $result = 0 === strpos($value, 'think_serialize:') ? unserialize(substr($value, 16)) : $value;
  93. } catch (\Exception $e) {
  94. $result = $default;
  95. }
  96. return $result;
  97. }
  98. /**
  99. * 写入缓存
  100. *
  101. * @access public
  102. *
  103. * @param string $name 缓存变量名
  104. * @param mixed $value 存储数据
  105. * @param integer|\DateTime $expire 有效时间(秒)
  106. *
  107. * @return boolean
  108. */
  109. public function set($name, $value, $expire = null) {
  110. if (is_null($expire)) {
  111. $expire = $this->options['expire'];
  112. }
  113. if ($expire instanceof \DateTime) {
  114. $expire = $expire->getTimestamp() - time();
  115. }
  116. if ($this->tag && !$this->has($name)) {
  117. $first = true;
  118. }
  119. $key = $this->getCacheKey($name);
  120. $value = is_scalar($value) ? $value : 'think_serialize:'.serialize($value);
  121. if ($expire) {
  122. $result = $this->handler->setex($key, $expire, $value);
  123. } else {
  124. $result = $this->handler->set($key, $value);
  125. }
  126. isset($first) && $this->setTagItem($key);
  127. return $result;
  128. }
  129. /**
  130. * 自增缓存(针对数值缓存)
  131. *
  132. * @access public
  133. *
  134. * @param string $name 缓存变量名
  135. * @param int $step 步长
  136. *
  137. * @return false|int
  138. */
  139. public function inc($name, $step = 1) {
  140. $key = $this->getCacheKey($name);
  141. return $this->handler->incrby($key, $step);
  142. }
  143. /**
  144. * 自减缓存(针对数值缓存)
  145. *
  146. * @access public
  147. *
  148. * @param string $name 缓存变量名
  149. * @param int $step 步长
  150. *
  151. * @return false|int
  152. */
  153. public function dec($name, $step = 1) {
  154. $key = $this->getCacheKey($name);
  155. return $this->handler->decrby($key, $step);
  156. }
  157. /**
  158. * 删除缓存
  159. *
  160. * @access public
  161. *
  162. * @param string $name 缓存变量名
  163. *
  164. * @return boolean
  165. */
  166. public function rm($name) {
  167. return $this->handler->del($this->getCacheKey($name));
  168. }
  169. /**
  170. * 清除缓存
  171. *
  172. * @access public
  173. *
  174. * @param string $tag 标签名
  175. *
  176. * @return boolean
  177. */
  178. public function clear($tag = null) {
  179. if ($tag) {
  180. // 指定标签清除
  181. $keys = $this->getTagItem($tag);
  182. foreach ($keys as $key) {
  183. $this->handler->del($key);
  184. }
  185. $this->rm('tag_'.md5($tag));
  186. return true;
  187. }
  188. return $this->handler->flushDB();
  189. }
  190. /**
  191. * Returns the keys that match a certain pattern.
  192. *
  193. * @param string $pattern pattern, using '*' as a wildcard.
  194. *
  195. * @return array of STRING: The keys that match a certain pattern.
  196. * @link https://redis.io/commands/keys
  197. * @example
  198. * <pre>
  199. * $allKeys = $redis->keys('*'); // all keys will match this.
  200. * $keyWithUserPrefix = $redis->keys('user*');
  201. * </pre>
  202. */
  203. public function keys($pattern) {
  204. return $this->handler->keys($pattern);
  205. }
  206. /**
  207. * @param string|string[] $key1 An array of keys, or an undefined number of parameters, each a key: key1 key2 key3
  208. * ... keyN
  209. * @param string $key2 ...
  210. * @param string $key3 ...
  211. *
  212. * @return int Number of keys deleted.
  213. * @see del()
  214. * @link https://redis.io/commands/del
  215. */
  216. public function delete($key1, $key2 = null, $key3 = null) {
  217. return $this->handler->del($key1, $key2, $key3);
  218. }
  219. /**
  220. * 返回缓存长度
  221. *
  222. * @param $name
  223. *
  224. * @return int
  225. */
  226. public function lLen($name) {
  227. return $this->handler->lLen($name);
  228. }
  229. /**
  230. * Returns and removes the first element of the list.
  231. *
  232. * @param $name
  233. *
  234. * @return string
  235. */
  236. public function lPop($name) {
  237. return $this->handler->lPop($name);
  238. }
  239. /**
  240. * Adds the string values to the head (left) of the list. Creates the list if the key didn't exist.
  241. * If the key exists and is not a list, FALSE is returned.
  242. *
  243. * @param string $key
  244. * @param string $value1
  245. * @param null $value2
  246. * @param null $valueN
  247. *
  248. * @return string
  249. */
  250. public function lPush($key, $value1, $value2 = null, $valueN = null) {
  251. return $this->handler->lPush($key, $value1, $value2, $valueN);
  252. }
  253. /**
  254. * Adds the specified member with a given score to the sorted set stored at key.
  255. *
  256. * @param string $key Required key
  257. * @param float $score1 Required score
  258. * @param string $value1 Required value
  259. * @param float $score2 Optional score
  260. * @param string $value2 Optional value
  261. * @param float $scoreN Optional score
  262. * @param string $valueN Optional value
  263. *
  264. * @return int Number of values added
  265. *
  266. * @return string
  267. */
  268. public function zAdd($key, $score1, $value1, $score2 = null, $value2 = null, $scoreN = null, $valueN = null) {
  269. return $this->handler->zAdd($key, $score1, $value1, $score2, $value2, $scoreN, $valueN);
  270. }
  271. /**
  272. * Deletes a specified member from the ordered set.
  273. *
  274. * @param string $key
  275. * @param string $member1
  276. * @param string $member2
  277. * @param string $memberN
  278. *
  279. * @return int Number of deleted values
  280. */
  281. public function zRem($key, $member1, $member2 = null, $memberN = null) {
  282. return $this->handler->zRem($key, $member1, $member2, $memberN);
  283. }
  284. /**
  285. * Returns the cardinality of an ordered set.
  286. *
  287. * @param string $key
  288. *
  289. * @return int the set's cardinality
  290. */
  291. public function zCard($key) {
  292. return $this->handler->zCard($key);
  293. }
  294. /**
  295. * Returns the cardinality of an ordered set.
  296. *
  297. * @param string $key
  298. *
  299. * @return int the set's cardinality
  300. */
  301. public function zSize($key) {
  302. return $this->handler->zCard($key);
  303. }
  304. /**
  305. * Increments the score of a member from a sorted set by a given amount.
  306. *
  307. * @param string $key
  308. * @param float $value (double) value that will be added to the member's score
  309. * @param string $member
  310. *
  311. * @return float the new value
  312. */
  313. public function zIncrBy($key, $value, $member) {
  314. return $this->handler->zIncrBy($key, $value, $member);
  315. }
  316. /**
  317. * Returns the number of elements of the sorted set stored at the specified key which have
  318. * scores in the range [start,end]. Adding a parenthesis before start or end excludes it
  319. * from the range. +inf and -inf are also valid limits.
  320. *
  321. * @param string $key
  322. * @param string $start
  323. * @param string $end
  324. *
  325. * @return int the size of a corresponding zRangeByScore.
  326. */
  327. public function zCount($key, $start, $end) {
  328. return $this->handler->zCount($key, $start, $end);
  329. }
  330. /**
  331. * Returns the rank of a given member in the specified sorted set, starting at 0 for the item
  332. * with the smallest score. zRevRank starts at 0 for the item with the largest score.
  333. *
  334. * @param string $key
  335. * @param string $member
  336. *
  337. * @return int the item's score.
  338. */
  339. public function zRank($key, $member) {
  340. return $this->handler->zRank($key, $member);
  341. }
  342. /**
  343. * Returns the score of a given member in the specified sorted set.
  344. *
  345. * @param string $key
  346. * @param string $member
  347. *
  348. * @return float
  349. */
  350. public function zScore($key, $member) {
  351. return $this->handler->zScore($key, $member);
  352. }
  353. /**
  354. * Returns a range of elements from the ordered set stored at the specified key,
  355. * with values in the range [start, end]. start and stop are interpreted as zero-based indices:
  356. * 0 the first element,
  357. * 1 the second ...
  358. * -1 the last element,
  359. * -2 the penultimate ...
  360. *
  361. * @param string $key
  362. * @param int $start
  363. * @param int $end
  364. * @param bool $with_scores
  365. *
  366. * @return array Array containing the values in specified range.
  367. */
  368. public function zRange($key, $start, $end, $with_scores = null) {
  369. return $this->handler->zRange($key, $start, $end, $with_scores);
  370. }
  371. /**
  372. * @param string $key
  373. * @param int $start
  374. * @param int $end
  375. * @param array $options
  376. *
  377. * @return array
  378. * @see zRangeByScore()
  379. *
  380. */
  381. public function zRevRangeByScore($key, $start, $end, array $options = array()) {
  382. return $this->handler->zRevRangeByScore($key, $start, $end, $options);
  383. }
  384. }