MemcachedStore.php 5.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. <?php
  2. namespace Illuminate\Cache;
  3. use Memcached;
  4. use ReflectionMethod;
  5. use Illuminate\Contracts\Cache\Store;
  6. use Illuminate\Support\InteractsWithTime;
  7. use Illuminate\Contracts\Cache\LockProvider;
  8. class MemcachedStore extends TaggableStore implements LockProvider, Store
  9. {
  10. use InteractsWithTime;
  11. /**
  12. * The Memcached instance.
  13. *
  14. * @var \Memcached
  15. */
  16. protected $memcached;
  17. /**
  18. * A string that should be prepended to keys.
  19. *
  20. * @var string
  21. */
  22. protected $prefix;
  23. /**
  24. * Indicates whether we are using Memcached version >= 3.0.0.
  25. *
  26. * @var bool
  27. */
  28. protected $onVersionThree;
  29. /**
  30. * Create a new Memcached store.
  31. *
  32. * @param \Memcached $memcached
  33. * @param string $prefix
  34. * @return void
  35. */
  36. public function __construct($memcached, $prefix = '')
  37. {
  38. $this->setPrefix($prefix);
  39. $this->memcached = $memcached;
  40. $this->onVersionThree = (new ReflectionMethod('Memcached', 'getMulti'))
  41. ->getNumberOfParameters() == 2;
  42. }
  43. /**
  44. * Retrieve an item from the cache by key.
  45. *
  46. * @param string $key
  47. * @return mixed
  48. */
  49. public function get($key)
  50. {
  51. $value = $this->memcached->get($this->prefix.$key);
  52. if ($this->memcached->getResultCode() == 0) {
  53. return $value;
  54. }
  55. }
  56. /**
  57. * Retrieve multiple items from the cache by key.
  58. *
  59. * Items not found in the cache will have a null value.
  60. *
  61. * @param array $keys
  62. * @return array
  63. */
  64. public function many(array $keys)
  65. {
  66. $prefixedKeys = array_map(function ($key) {
  67. return $this->prefix.$key;
  68. }, $keys);
  69. if ($this->onVersionThree) {
  70. $values = $this->memcached->getMulti($prefixedKeys, Memcached::GET_PRESERVE_ORDER);
  71. } else {
  72. $null = null;
  73. $values = $this->memcached->getMulti($prefixedKeys, $null, Memcached::GET_PRESERVE_ORDER);
  74. }
  75. if ($this->memcached->getResultCode() != 0) {
  76. return array_fill_keys($keys, null);
  77. }
  78. return array_combine($keys, $values);
  79. }
  80. /**
  81. * Store an item in the cache for a given number of minutes.
  82. *
  83. * @param string $key
  84. * @param mixed $value
  85. * @param float|int $minutes
  86. * @return void
  87. */
  88. public function put($key, $value, $minutes)
  89. {
  90. $this->memcached->set($this->prefix.$key, $value, $this->toTimestamp($minutes));
  91. }
  92. /**
  93. * Store multiple items in the cache for a given number of minutes.
  94. *
  95. * @param array $values
  96. * @param float|int $minutes
  97. * @return void
  98. */
  99. public function putMany(array $values, $minutes)
  100. {
  101. $prefixedValues = [];
  102. foreach ($values as $key => $value) {
  103. $prefixedValues[$this->prefix.$key] = $value;
  104. }
  105. $this->memcached->setMulti($prefixedValues, $this->toTimestamp($minutes));
  106. }
  107. /**
  108. * Store an item in the cache if the key doesn't exist.
  109. *
  110. * @param string $key
  111. * @param mixed $value
  112. * @param float|int $minutes
  113. * @return bool
  114. */
  115. public function add($key, $value, $minutes)
  116. {
  117. return $this->memcached->add($this->prefix.$key, $value, $this->toTimestamp($minutes));
  118. }
  119. /**
  120. * Increment the value of an item in the cache.
  121. *
  122. * @param string $key
  123. * @param mixed $value
  124. * @return int|bool
  125. */
  126. public function increment($key, $value = 1)
  127. {
  128. return $this->memcached->increment($this->prefix.$key, $value);
  129. }
  130. /**
  131. * Decrement the value of an item in the cache.
  132. *
  133. * @param string $key
  134. * @param mixed $value
  135. * @return int|bool
  136. */
  137. public function decrement($key, $value = 1)
  138. {
  139. return $this->memcached->decrement($this->prefix.$key, $value);
  140. }
  141. /**
  142. * Store an item in the cache indefinitely.
  143. *
  144. * @param string $key
  145. * @param mixed $value
  146. * @return void
  147. */
  148. public function forever($key, $value)
  149. {
  150. $this->put($key, $value, 0);
  151. }
  152. /**
  153. * Get a lock instance.
  154. *
  155. * @param string $name
  156. * @param int $seconds
  157. * @return \Illuminate\Contracts\Cache\Lock
  158. */
  159. public function lock($name, $seconds = 0)
  160. {
  161. return new MemcachedLock($this->memcached, $this->prefix.$name, $seconds);
  162. }
  163. /**
  164. * Remove an item from the cache.
  165. *
  166. * @param string $key
  167. * @return bool
  168. */
  169. public function forget($key)
  170. {
  171. return $this->memcached->delete($this->prefix.$key);
  172. }
  173. /**
  174. * Remove all items from the cache.
  175. *
  176. * @return bool
  177. */
  178. public function flush()
  179. {
  180. return $this->memcached->flush();
  181. }
  182. /**
  183. * Get the UNIX timestamp for the given number of minutes.
  184. *
  185. * @param int $minutes
  186. * @return int
  187. */
  188. protected function toTimestamp($minutes)
  189. {
  190. return $minutes > 0 ? $this->availableAt($minutes * 60) : 0;
  191. }
  192. /**
  193. * Get the underlying Memcached connection.
  194. *
  195. * @return \Memcached
  196. */
  197. public function getMemcached()
  198. {
  199. return $this->memcached;
  200. }
  201. /**
  202. * Get the cache key prefix.
  203. *
  204. * @return string
  205. */
  206. public function getPrefix()
  207. {
  208. return $this->prefix;
  209. }
  210. /**
  211. * Set the cache key prefix.
  212. *
  213. * @param string $prefix
  214. * @return void
  215. */
  216. public function setPrefix($prefix)
  217. {
  218. $this->prefix = ! empty($prefix) ? $prefix.':' : '';
  219. }
  220. }