You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

232 lines
6.0 KiB

  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;
  12. /**
  13. * 缓存基础类
  14. */
  15. abstract class Driver
  16. {
  17. protected $handler = null;
  18. protected $options = [];
  19. protected $tag;
  20. /**
  21. * 判断缓存是否存在
  22. * @access public
  23. * @param string $name 缓存变量名
  24. * @return bool
  25. */
  26. abstract public function has($name);
  27. /**
  28. * 读取缓存
  29. * @access public
  30. * @param string $name 缓存变量名
  31. * @param mixed $default 默认值
  32. * @return mixed
  33. */
  34. abstract public function get($name, $default = false);
  35. /**
  36. * 写入缓存
  37. * @access public
  38. * @param string $name 缓存变量名
  39. * @param mixed $value 存储数据
  40. * @param int $expire 有效时间 0为永久
  41. * @return boolean
  42. */
  43. abstract public function set($name, $value, $expire = null);
  44. /**
  45. * 自增缓存(针对数值缓存)
  46. * @access public
  47. * @param string $name 缓存变量名
  48. * @param int $step 步长
  49. * @return false|int
  50. */
  51. abstract public function inc($name, $step = 1);
  52. /**
  53. * 自减缓存(针对数值缓存)
  54. * @access public
  55. * @param string $name 缓存变量名
  56. * @param int $step 步长
  57. * @return false|int
  58. */
  59. abstract public function dec($name, $step = 1);
  60. /**
  61. * 删除缓存
  62. * @access public
  63. * @param string $name 缓存变量名
  64. * @return boolean
  65. */
  66. abstract public function rm($name);
  67. /**
  68. * 清除缓存
  69. * @access public
  70. * @param string $tag 标签名
  71. * @return boolean
  72. */
  73. abstract public function clear($tag = null);
  74. /**
  75. * 获取实际的缓存标识
  76. * @access public
  77. * @param string $name 缓存名
  78. * @return string
  79. */
  80. protected function getCacheKey($name)
  81. {
  82. return $this->options['prefix'] . $name;
  83. }
  84. /**
  85. * 读取缓存并删除
  86. * @access public
  87. * @param string $name 缓存变量名
  88. * @return mixed
  89. */
  90. public function pull($name)
  91. {
  92. $result = $this->get($name, false);
  93. if ($result) {
  94. $this->rm($name);
  95. return $result;
  96. } else {
  97. return;
  98. }
  99. }
  100. /**
  101. * 如果不存在则写入缓存
  102. * @access public
  103. * @param string $name 缓存变量名
  104. * @param mixed $value 存储数据
  105. * @param int $expire 有效时间 0为永久
  106. * @return mixed
  107. */
  108. public function remember($name, $value, $expire = null)
  109. {
  110. if (!$this->has($name)) {
  111. $time = time();
  112. while ($time + 5 > time() && $this->has($name . '_lock')) {
  113. // 存在锁定则等待
  114. usleep(200000);
  115. }
  116. try {
  117. // 锁定
  118. $this->set($name . '_lock', true);
  119. if ($value instanceof \Closure) {
  120. $value = call_user_func($value);
  121. }
  122. $this->set($name, $value, $expire);
  123. // 解锁
  124. $this->rm($name . '_lock');
  125. } catch (\Exception $e) {
  126. // 解锁
  127. $this->rm($name . '_lock');
  128. throw $e;
  129. } catch (\throwable $e) {
  130. $this->rm($name . '_lock');
  131. throw $e;
  132. }
  133. } else {
  134. $value = $this->get($name);
  135. }
  136. return $value;
  137. }
  138. /**
  139. * 缓存标签
  140. * @access public
  141. * @param string $name 标签名
  142. * @param string|array $keys 缓存标识
  143. * @param bool $overlay 是否覆盖
  144. * @return $this
  145. */
  146. public function tag($name, $keys = null, $overlay = false)
  147. {
  148. if (is_null($name)) {
  149. } elseif (is_null($keys)) {
  150. $this->tag = $name;
  151. } else {
  152. $key = 'tag_' . md5($name);
  153. if (is_string($keys)) {
  154. $keys = explode(',', $keys);
  155. }
  156. $keys = array_map([$this, 'getCacheKey'], $keys);
  157. if ($overlay) {
  158. $value = $keys;
  159. } else {
  160. $value = array_unique(array_merge($this->getTagItem($name), $keys));
  161. }
  162. $this->set($key, implode(',', $value), 0);
  163. }
  164. return $this;
  165. }
  166. /**
  167. * 更新标签
  168. * @access public
  169. * @param string $name 缓存标识
  170. * @return void
  171. */
  172. protected function setTagItem($name)
  173. {
  174. if ($this->tag) {
  175. $key = 'tag_' . md5($this->tag);
  176. $this->tag = null;
  177. if ($this->has($key)) {
  178. $value = explode(',', $this->get($key));
  179. $value[] = $name;
  180. $value = implode(',', array_unique($value));
  181. } else {
  182. $value = $name;
  183. }
  184. $this->set($key, $value, 0);
  185. }
  186. }
  187. /**
  188. * 获取标签包含的缓存标识
  189. * @access public
  190. * @param string $tag 缓存标签
  191. * @return array
  192. */
  193. protected function getTagItem($tag)
  194. {
  195. $key = 'tag_' . md5($tag);
  196. $value = $this->get($key);
  197. if ($value) {
  198. return array_filter(explode(',', $value));
  199. } else {
  200. return [];
  201. }
  202. }
  203. /**
  204. * 返回句柄对象,可执行其它高级方法
  205. *
  206. * @access public
  207. * @return object
  208. */
  209. public function handler()
  210. {
  211. return $this->handler;
  212. }
  213. }