From 631334b31e309d5794c395d001ed96b37a622690 Mon Sep 17 00:00:00 2001 From: thinkphp Date: Wed, 17 Aug 2016 16:12:49 +0800 Subject: [PATCH] =?UTF-8?q?=E7=BC=93=E5=AD=98=E7=B1=BB=E5=A2=9E=E5=8A=A0ta?= =?UTF-8?q?g=E6=96=B9=E6=B3=95=20=E7=94=A8=E4=BA=8E=E7=BC=93=E5=AD=98?= =?UTF-8?q?=E6=A0=87=E7=AD=BE=E8=AE=BE=E7=BD=AE=20clear=E6=96=B9=E6=B3=95?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E6=B8=85=E9=99=A4=E6=9F=90=E4=B8=AA=E7=BC=93?= =?UTF-8?q?=E5=AD=98=E6=A0=87=E7=AD=BE=E7=9A=84=E6=95=B0=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- library/think/Cache.php | 17 ++- library/think/cache/Driver.php | 132 +++++++++++++++++++++++ library/think/cache/driver/File.php | 22 +++- library/think/cache/driver/Lite.php | 25 +++-- library/think/cache/driver/Memcache.php | 18 +++- library/think/cache/driver/Memcached.php | 17 ++- library/think/cache/driver/Redis.php | 15 ++- library/think/cache/driver/Sqlite.php | 22 +++- library/think/cache/driver/Wincache.php | 23 +++- library/think/cache/driver/Xcache.php | 18 +++- 10 files changed, 283 insertions(+), 26 deletions(-) create mode 100644 library/think/cache/Driver.php diff --git a/library/think/Cache.php b/library/think/Cache.php index 3bbd3e3a..a958911d 100644 --- a/library/think/Cache.php +++ b/library/think/Cache.php @@ -155,13 +155,26 @@ class Cache /** * 清除缓存 * @access public + * @param string $tag 标签名 * @return boolean */ - public static function clear() + public static function clear($tag = null) { self::init(); self::$writeTimes++; - return self::$handler->clear(); + return self::$handler->clear($tag); + } + + /** + * 缓存标签 + * @access public + * @param string $name 标签名 + * @return \think\cache\Driver + */ + public static function tag($name) + { + self::init(); + return self::$handler->tag($name); } } diff --git a/library/think/cache/Driver.php b/library/think/cache/Driver.php new file mode 100644 index 00000000..0ea61fc6 --- /dev/null +++ b/library/think/cache/Driver.php @@ -0,0 +1,132 @@ + +// +---------------------------------------------------------------------- + +namespace think\cache\driver; + +/** + * 缓存基础类 + */ +abstract class Driver +{ + protected $options = []; + protected $tag; + + /** + * 判断缓存是否存在 + * @access public + * @param string $name 缓存变量名 + * @return bool + */ + abstract public function has($name); + + /** + * 读取缓存 + * @access public + * @param string $name 缓存变量名 + * @param mixed $default 默认值 + * @return mixed + */ + abstract public function get($name, $default = false); + + /** + * 写入缓存 + * @access public + * @param string $name 缓存变量名 + * @param mixed $value 存储数据 + * @param int $expire 有效时间 0为永久 + * @return boolean + */ + abstract public function set($name, $value, $expire = null); + + /** + * 自增缓存(针对数值缓存) + * @access public + * @param string $name 缓存变量名 + * @param int $step 步长 + * @return false|int + */ + abstract public function inc($name, $step = 1); + + /** + * 自减缓存(针对数值缓存) + * @access public + * @param string $name 缓存变量名 + * @param int $step 步长 + * @return false|int + */ + abstract public function dec($name, $step = 1); + + /** + * 删除缓存 + * @access public + * @param string $name 缓存变量名 + * @return boolean + */ + abstract public function rm($name); + + /** + * 清除缓存 + * @access public + * @param string $tag 标签名 + * @return boolean + */ + abstract public function clear($tag = null); + + /** + * 缓存标签 + * @access public + * @param string $name 标签名 + * @return $this + */ + public function tag($name) + { + $this->tag = $name; + return $this; + } + + /** + * 更新标签 + * @access public + * @param string $name 缓存标识 + * @return void + */ + protected function setTagItem($name) + { + if ($this->tag) { + $key = 'tag_' . md5($this->tag); + $this->tag = null; + if ($this->has($key)) { + $value = $this->get($key); + $value .= ',' . $name; + } else { + $value = $name; + } + $this->set($key, $value); + } + } + + /** + * 获取标签包含的缓存标识 + * @access public + * @param string $tag 缓存标签 + * @return array + */ + protected function getTagItem($tag) + { + $key = 'tag_' . md5($tag); + $value = $this->get($key); + if ($value) { + return explode(',', $value); + } else { + return []; + } + } +} diff --git a/library/think/cache/driver/File.php b/library/think/cache/driver/File.php index 1f4b91f8..c45f1f87 100644 --- a/library/think/cache/driver/File.php +++ b/library/think/cache/driver/File.php @@ -11,11 +11,13 @@ namespace think\cache\driver; +use think\cache\Driver; + /** * 文件类型缓存类 * @author liu21st */ -class File +class File extends Driver { protected $options = [ 'expire' => 0, @@ -139,7 +141,10 @@ class File $expire = $this->options['expire']; } $filename = $this->filename($name); - $data = serialize($value); + if ($this->tag && !is_file($filename)) { + $first = true; + } + $data = serialize($value); if ($this->options['data_compress'] && function_exists('gzcompress')) { //数据压缩 $data = gzcompress($data, 3); @@ -147,6 +152,7 @@ class File $data = ""; $result = file_put_contents($filename, $data); if ($result) { + isset($first) && setTagItem($filename); clearstatcache(); return true; } else { @@ -202,10 +208,19 @@ class File /** * 清除缓存 * @access public + * @param string $tag 标签名 * @return boolean */ - public function clear() + public function clear($tag = null) { + if ($tag) { + // 指定标签清除 + $keys = $this->getTagItem($tag); + foreach ($keys as $key) { + $this->unlink($key); + } + return true; + } $fileLsit = (array) glob($this->options['path'] . '*'); foreach ($fileLsit as $path) { is_file($path) && unlink($path); @@ -224,4 +239,5 @@ class File { return is_file($path) && unlink($path); } + } diff --git a/library/think/cache/driver/Lite.php b/library/think/cache/driver/Lite.php index 41c94d06..4ae82e6e 100644 --- a/library/think/cache/driver/Lite.php +++ b/library/think/cache/driver/Lite.php @@ -11,11 +11,13 @@ namespace think\cache\driver; +use think\cache\Driver; + /** * 文件类型缓存类 * @author liu21st */ -class Lite +class Lite extends Driver { protected $options = [ 'prefix' => '', @@ -105,9 +107,13 @@ class Lite $expire = 10 * 365 * 24 * 3600; } $filename = $this->filename($name); - $ret = file_put_contents($filename, ("tag && !is_file($filename)) { + $first = true; + } + $ret = file_put_contents($filename, ("setTagItem($filename); touch($filename, $_SERVER['REQUEST_TIME'] + $expire); } return $ret; @@ -161,12 +167,19 @@ class Lite /** * 清除缓存 * @access public + * @param string $tag 标签名 * @return bool - * @internal param string $name 缓存变量名 */ - public function clear() + public function clear($tag = null) { - $filename = $this->filename('*'); - array_map("unlink", glob($filename)); + if ($tag) { + // 指定标签清除 + $keys = $this->getTagItem($tag); + foreach ($keys as $key) { + unlink($key); + } + return true; + } + array_map("unlink", glob($this->options['path'] . $this->options['prefix'] . '*.php')); } } diff --git a/library/think/cache/driver/Memcache.php b/library/think/cache/driver/Memcache.php index aacba930..2beb5837 100644 --- a/library/think/cache/driver/Memcache.php +++ b/library/think/cache/driver/Memcache.php @@ -11,9 +11,10 @@ namespace think\cache\driver; +use think\cache\Driver; use think\Exception; -class Memcache +class Memcache extends Driver { protected $handler = null; protected $options = [ @@ -93,8 +94,12 @@ class Memcache if (is_null($expire)) { $expire = $this->options['expire']; } + if ($this->tag && !$this->has($name)) { + $first = true; + } $name = $this->options['prefix'] . $name; if ($this->handler->set($name, $value, 0, $expire)) { + isset($first) && $this->setTagItem($name); return true; } return false; @@ -149,10 +154,19 @@ class Memcache /** * 清除缓存 * @access public + * @param string $tag 标签名 * @return bool */ - public function clear() + public function clear($tag = null) { + if ($tag) { + // 指定标签清除 + $keys = $this->getTagItem($tag); + foreach ($keys as $key) { + $this->handler->delete($key); + } + return true; + } return $this->handler->flush(); } } diff --git a/library/think/cache/driver/Memcached.php b/library/think/cache/driver/Memcached.php index f260fec6..78be1069 100644 --- a/library/think/cache/driver/Memcached.php +++ b/library/think/cache/driver/Memcached.php @@ -11,7 +11,9 @@ namespace think\cache\driver; -class Memcached +use think\cache\Driver; + +class Memcached extends Driver { protected $handler; protected $options = [ @@ -98,9 +100,13 @@ class Memcached if (is_null($expire)) { $expire = $this->options['expire']; } + if ($this->tag && !$this->has($name)) { + $first = true; + } $name = $this->options['prefix'] . $name; $expire = 0 == $expire ? 0 : $_SERVER['REQUEST_TIME'] + $expire; if ($this->handler->set($name, $value, $expire)) { + isset($first) && $this->setTagItem($name); return true; } return false; @@ -155,10 +161,17 @@ class Memcached /** * 清除缓存 * @access public + * @param string $tag 标签名 * @return bool */ - public function clear() + public function clear($tag = null) { + if ($tag) { + // 指定标签清除 + $keys = $this->getTagItem($tag); + $this->handler->deleteMulti($keys); + return true; + } return $this->handler->flush(); } } diff --git a/library/think/cache/driver/Redis.php b/library/think/cache/driver/Redis.php index 4caa3fb8..6dbc4844 100644 --- a/library/think/cache/driver/Redis.php +++ b/library/think/cache/driver/Redis.php @@ -11,6 +11,8 @@ namespace think\cache\driver; +use think\cache\Driver; + /** * Redis缓存驱动,适合单机部署、有前端代理实现高可用的场景,性能最好 * 有需要在业务层实现读写分离、或者使用RedisCluster的需求,请使用Redisd驱动 @@ -18,7 +20,7 @@ namespace think\cache\driver; * 要求安装phpredis扩展:https://github.com/nicolasff/phpredis * @author 尘缘 <130775@qq.com> */ -class Redis +class Redis extends Driver { protected $handler = null; protected $options = [ @@ -146,10 +148,19 @@ class Redis /** * 清除缓存 * @access public + * @param string $tag 标签名 * @return boolean */ - public function clear() + public function clear($tag = null) { + if ($tag) { + // 指定标签清除 + $keys = $this->getTagItem($tag); + foreach ($keys as $key) { + $this->handler->delete($key); + } + return true; + } return $this->handler->flushDB(); } diff --git a/library/think/cache/driver/Sqlite.php b/library/think/cache/driver/Sqlite.php index a7cbfa01..392cd1fb 100644 --- a/library/think/cache/driver/Sqlite.php +++ b/library/think/cache/driver/Sqlite.php @@ -11,13 +11,14 @@ namespace think\cache\driver; +use think\cache\Driver; use think\Exception; /** * Sqlite缓存驱动 * @author liu21st */ -class Sqlite +class Sqlite extends Driver { protected $options = [ @@ -103,7 +104,13 @@ class Sqlite //数据压缩 $value = gzcompress($value, 3); } - $sql = 'REPLACE INTO ' . $this->options['table'] . ' (var, value,expire) VALUES (\'' . $name . '\', \'' . $value . '\', \'' . $expire . '\')'; + if ($this->tag) { + $tag = $this->tag; + $this->tag = null; + } else { + $tag = ''; + } + $sql = 'REPLACE INTO ' . $this->options['table'] . ' (var, value, expire, tag) VALUES (\'' . $name . '\', \'' . $value . '\', \'' . $expire . '\', \'' . $tag . '\')'; if (sqlite_query($this->handler, $sql)) { return true; } @@ -161,12 +168,19 @@ class Sqlite /** * 清除缓存 * @access public + * @param string $tag 标签名 * @return boolean */ - public function clear() + public function clear($tag = null) { + if ($tag) { + $name = sqlite_escape_string($tag); + $sql = 'DELETE FROM ' . $this->options['table'] . ' WHERE tag=\'' . $name . '\''; + sqlite_query($this->handler, $sql); + return true; + } $sql = 'DELETE FROM ' . $this->options['table']; sqlite_query($this->handler, $sql); - return; + return true; } } diff --git a/library/think/cache/driver/Wincache.php b/library/think/cache/driver/Wincache.php index 77fb74a4..e529fe28 100644 --- a/library/think/cache/driver/Wincache.php +++ b/library/think/cache/driver/Wincache.php @@ -11,19 +11,22 @@ namespace think\cache\driver; +use think\cache\Driver; use think\Exception; /** * Wincache缓存驱动 * @author liu21st */ -class Wincache +class Wincache extends Driver { protected $options = [ 'prefix' => '', 'expire' => 0, ]; + protected $tag; + /** * 架构函数 * @param array $options 缓存参数 @@ -79,7 +82,11 @@ class Wincache $expire = $this->options['expire']; } $name = $this->options['prefix'] . $name; + if ($this->tag && !$this->has($name)) { + $first = true; + } if (wincache_ucache_set($name, $value, $expire)) { + isset($first) && $this->setTagItem($name); return true; } return false; @@ -125,10 +132,20 @@ class Wincache /** * 清除缓存 * @access public + * @param string $tag 标签名 * @return boolean */ - public function clear() + public function clear($tag = null) { - return; + if ($tag) { + $keys = $this->getTagItem($tag); + foreach ($keys as $key) { + wincache_ucache_delete($key); + } + return true; + } else { + return wincache_ucache_clear(); + } } + } diff --git a/library/think/cache/driver/Xcache.php b/library/think/cache/driver/Xcache.php index e012112f..18a76d2f 100644 --- a/library/think/cache/driver/Xcache.php +++ b/library/think/cache/driver/Xcache.php @@ -11,13 +11,14 @@ namespace think\cache\driver; +use think\cache\Driver; use think\Exception; /** * Xcache缓存驱动 * @author liu21st */ -class Xcache +class Xcache extends Driver { protected $options = [ 'prefix' => '', @@ -78,8 +79,12 @@ class Xcache if (is_null($expire)) { $expire = $this->options['expire']; } + if ($this->tag && !$this->has($name)) { + $first = true; + } $name = $this->options['prefix'] . $name; if (xcache_set($name, $value, $expire)) { + isset($first) && $this->setTagItem($name); return true; } return false; @@ -125,10 +130,19 @@ class Xcache /** * 清除缓存 * @access public + * @param string $tag 标签名 * @return boolean */ - public function clear() + public function clear($tag = null) { + if ($tag) { + // 指定标签清除 + $keys = $this->getTagItem($tag); + foreach ($keys as $key) { + xcache_unset($key); + } + return true; + } if (function_exists('xcache_unset_by_prefix')) { return xcache_unset_by_prefix($this->options['prefix']); } else {