RedisStore.php 6.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  1. <?php
  2. namespace Illuminate\Cache;
  3. use Illuminate\Contracts\Cache\Store;
  4. use Illuminate\Contracts\Redis\Factory as Redis;
  5. class RedisStore extends TaggableStore implements Store
  6. {
  7. /**
  8. * The Redis factory implementation.
  9. *
  10. * @var \Illuminate\Contracts\Redis\Factory
  11. */
  12. protected $redis;
  13. /**
  14. * A string that should be prepended to keys.
  15. *
  16. * @var string
  17. */
  18. protected $prefix;
  19. /**
  20. * The Redis connection that should be used.
  21. *
  22. * @var string
  23. */
  24. protected $connection;
  25. /**
  26. * Create a new Redis store.
  27. *
  28. * @param \Illuminate\Contracts\Redis\Factory $redis
  29. * @param string $prefix
  30. * @param string $connection
  31. * @return void
  32. */
  33. public function __construct(Redis $redis, $prefix = '', $connection = 'default')
  34. {
  35. $this->redis = $redis;
  36. $this->setPrefix($prefix);
  37. $this->setConnection($connection);
  38. }
  39. /**
  40. * Retrieve an item from the cache by key.
  41. *
  42. * @param string|array $key
  43. * @return mixed
  44. */
  45. public function get($key)
  46. {
  47. $value = $this->connection()->get($this->prefix.$key);
  48. return ! is_null($value) ? $this->unserialize($value) : null;
  49. }
  50. /**
  51. * Retrieve multiple items from the cache by key.
  52. *
  53. * Items not found in the cache will have a null value.
  54. *
  55. * @param array $keys
  56. * @return array
  57. */
  58. public function many(array $keys)
  59. {
  60. $results = [];
  61. $values = $this->connection()->mget(array_map(function ($key) {
  62. return $this->prefix.$key;
  63. }, $keys));
  64. foreach ($values as $index => $value) {
  65. $results[$keys[$index]] = ! is_null($value) ? $this->unserialize($value) : null;
  66. }
  67. return $results;
  68. }
  69. /**
  70. * Store an item in the cache for a given number of minutes.
  71. *
  72. * @param string $key
  73. * @param mixed $value
  74. * @param float|int $minutes
  75. * @return void
  76. */
  77. public function put($key, $value, $minutes)
  78. {
  79. $this->connection()->setex(
  80. $this->prefix.$key, (int) max(1, $minutes * 60), $this->serialize($value)
  81. );
  82. }
  83. /**
  84. * Store multiple items in the cache for a given number of minutes.
  85. *
  86. * @param array $values
  87. * @param float|int $minutes
  88. * @return void
  89. */
  90. public function putMany(array $values, $minutes)
  91. {
  92. $this->connection()->multi();
  93. foreach ($values as $key => $value) {
  94. $this->put($key, $value, $minutes);
  95. }
  96. $this->connection()->exec();
  97. }
  98. /**
  99. * Store an item in the cache if the key doesn't exist.
  100. *
  101. * @param string $key
  102. * @param mixed $value
  103. * @param float|int $minutes
  104. * @return bool
  105. */
  106. public function add($key, $value, $minutes)
  107. {
  108. $lua = "return redis.call('exists',KEYS[1])<1 and redis.call('setex',KEYS[1],ARGV[2],ARGV[1])";
  109. return (bool) $this->connection()->eval(
  110. $lua, 1, $this->prefix.$key, $this->serialize($value), (int) max(1, $minutes * 60)
  111. );
  112. }
  113. /**
  114. * Increment the value of an item in the cache.
  115. *
  116. * @param string $key
  117. * @param mixed $value
  118. * @return int
  119. */
  120. public function increment($key, $value = 1)
  121. {
  122. return $this->connection()->incrby($this->prefix.$key, $value);
  123. }
  124. /**
  125. * Decrement the value of an item in the cache.
  126. *
  127. * @param string $key
  128. * @param mixed $value
  129. * @return int
  130. */
  131. public function decrement($key, $value = 1)
  132. {
  133. return $this->connection()->decrby($this->prefix.$key, $value);
  134. }
  135. /**
  136. * Store an item in the cache indefinitely.
  137. *
  138. * @param string $key
  139. * @param mixed $value
  140. * @return void
  141. */
  142. public function forever($key, $value)
  143. {
  144. $this->connection()->set($this->prefix.$key, $this->serialize($value));
  145. }
  146. /**
  147. * Get a lock instance.
  148. *
  149. * @param string $name
  150. * @param int $seconds
  151. * @return \Illuminate\Contracts\Cache\Lock
  152. */
  153. public function lock($name, $seconds = 0)
  154. {
  155. return new RedisLock($this->connection(), $this->prefix.$name, $seconds);
  156. }
  157. /**
  158. * Remove an item from the cache.
  159. *
  160. * @param string $key
  161. * @return bool
  162. */
  163. public function forget($key)
  164. {
  165. return (bool) $this->connection()->del($this->prefix.$key);
  166. }
  167. /**
  168. * Remove all items from the cache.
  169. *
  170. * @return bool
  171. */
  172. public function flush()
  173. {
  174. $this->connection()->flushdb();
  175. return true;
  176. }
  177. /**
  178. * Begin executing a new tags operation.
  179. *
  180. * @param array|mixed $names
  181. * @return \Illuminate\Cache\RedisTaggedCache
  182. */
  183. public function tags($names)
  184. {
  185. return new RedisTaggedCache(
  186. $this, new TagSet($this, is_array($names) ? $names : func_get_args())
  187. );
  188. }
  189. /**
  190. * Get the Redis connection instance.
  191. *
  192. * @return \Predis\ClientInterface
  193. */
  194. public function connection()
  195. {
  196. return $this->redis->connection($this->connection);
  197. }
  198. /**
  199. * Set the connection name to be used.
  200. *
  201. * @param string $connection
  202. * @return void
  203. */
  204. public function setConnection($connection)
  205. {
  206. $this->connection = $connection;
  207. }
  208. /**
  209. * Get the Redis database instance.
  210. *
  211. * @return \Illuminate\Contracts\Redis\Factory
  212. */
  213. public function getRedis()
  214. {
  215. return $this->redis;
  216. }
  217. /**
  218. * Get the cache key prefix.
  219. *
  220. * @return string
  221. */
  222. public function getPrefix()
  223. {
  224. return $this->prefix;
  225. }
  226. /**
  227. * Set the cache key prefix.
  228. *
  229. * @param string $prefix
  230. * @return void
  231. */
  232. public function setPrefix($prefix)
  233. {
  234. $this->prefix = ! empty($prefix) ? $prefix.':' : '';
  235. }
  236. /**
  237. * Serialize the value.
  238. *
  239. * @param mixed $value
  240. * @return mixed
  241. */
  242. protected function serialize($value)
  243. {
  244. return is_numeric($value) ? $value : serialize($value);
  245. }
  246. /**
  247. * Unserialize the value.
  248. *
  249. * @param mixed $value
  250. * @return mixed
  251. */
  252. protected function unserialize($value)
  253. {
  254. return is_numeric($value) ? $value : unserialize($value);
  255. }
  256. }