├── Plugin.php ├── README.md └── driver ├── cache.interface.php ├── typecho_memcache.class.php ├── typecho_memcached.class.php ├── typecho_mysql.class.php └── typecho_redis.class.php /Plugin.php: -------------------------------------------------------------------------------- 1 | begin = array('TpCache_Plugin', 'C'); 26 | Typecho_Plugin::factory('index.php')->end = array('TpCache_Plugin', 'S'); 27 | 28 | //页面编辑 29 | Typecho_Plugin::factory('Widget_Contents_Post_Edit')->finishPublish = array('TpCache_Plugin', 'post_update'); 30 | Typecho_Plugin::factory('Widget_Contents_Page_Edit')->finishPublish = array('TpCache_Plugin', 'post_update'); 31 | 32 | //评论 33 | Typecho_Plugin::factory('Widget_Feedback')->finishComment = array('TpCache_Plugin', 'comment_update'); 34 | 35 | 36 | return '插件安装成功,请设置需要缓存的页面'; 37 | } 38 | 39 | /** 40 | * 禁用插件方法,如果禁用失败,直接抛出异常 41 | * 42 | * @static 43 | * @access public 44 | * @throws Typecho_Plugin_Exception 45 | */ 46 | public static function deactivate() 47 | { 48 | try { 49 | $uninstall_sql = 'DROP TABLE IF EXISTS `%prefix%cache`'; 50 | $db = Typecho_Db::get(); 51 | $prefix = $db->getPrefix(); 52 | $sql = str_replace('%prefix%', $prefix, $uninstall_sql); 53 | $db->query($sql); 54 | } catch (Exception $e) { 55 | echo $e->getMessage(); 56 | } 57 | } 58 | 59 | /** 60 | * 获取插件配置面板 61 | * 62 | * @access public 63 | * @param Typecho_Widget_Helper_Form $form 配置面板 64 | * @return void 65 | */ 66 | public static function config(Typecho_Widget_Helper_Form $form) 67 | { 68 | 69 | $list = array( 70 | 'index' => '首页', 71 | 'archive' => '归档', 72 | 'post' => '文章', 73 | 'attachment' => '附件', 74 | 'category' => '分类', 75 | 'tag' => '标签', 76 | 'author' => '作者', 77 | 'search' => '搜索', 78 | 'feed' => 'feed', 79 | 'page' => '页面', 80 | ); 81 | $element = new Typecho_Widget_Helper_Form_Element_Checkbox('cache_page', $list, array('index', 'post', 'search', 'page', 'author', 'tag'), '需要缓存的页面'); 82 | $form->addInput($element); 83 | 84 | $list = array('关闭', '开启'); 85 | $element = new Typecho_Widget_Helper_Form_Element_Radio('login', $list, 1, '是否对已登录用户失效', '已经录用户不会触发缓存策略'); 86 | $form->addInput($element); 87 | 88 | $list = array('关闭', '开启'); 89 | $element = new Typecho_Widget_Helper_Form_Element_Radio('enable_ssl', $list, '0', '是否支持SSL'); 90 | $form->addInput($element); 91 | 92 | $list = array( 93 | '0' => '不使用缓存', 94 | 'memcached' => 'Memcached', 95 | 'memcache' => 'Memcache', 96 | 'redis' => 'Redis', 97 | 'mysql' => 'Mysql' 98 | ); 99 | $element = new Typecho_Widget_Helper_Form_Element_Radio('cache_driver', $list, '0', '缓存驱动'); 100 | $form->addInput($element); 101 | 102 | $element = new Typecho_Widget_Helper_Form_Element_Text('expire', null, '86400', '缓存过期时间', '86400 = 60s * 60m *24h,即一天的秒数'); 103 | $form->addInput($element); 104 | 105 | $element = new Typecho_Widget_Helper_Form_Element_Text('host', null, '127.0.0.1', '主机地址', '主机地址,一般为127.0.0.1'); 106 | $form->addInput($element); 107 | 108 | $element = new Typecho_Widget_Helper_Form_Element_Text('port', null, '11211', '端口号', '端口号,memcache对应11211,Redis对应6379,其他类型随意填写'); 109 | $form->addInput($element); 110 | 111 | $list = array('关闭', '开启'); 112 | $element = new Typecho_Widget_Helper_Form_Element_Radio('is_debug', $list, 0, '是否开启debug'); 113 | $form->addInput($element); 114 | 115 | $list = array('关闭', '清除所有数据'); 116 | $element = new Typecho_Widget_Helper_Form_Element_Radio('is_clean', $list, 0, '清除所有数据'); 117 | $form->addInput($element); 118 | } 119 | 120 | /** 121 | * 手动保存配置句柄 122 | * @param $config array 插件配置 123 | * @param $is_init bool 是否初始化 124 | */ 125 | public static function configHandle($config, $is_init) 126 | { 127 | if ($is_init != true && $config['cache_driver'] != '0') { 128 | 129 | $driver_name = $config['cache_driver']; 130 | $class_name = "typecho_$driver_name"; 131 | $file_path = "driver/$class_name.class.php"; 132 | require_once 'driver/cache.interface.php'; 133 | require_once $file_path; 134 | self::$cache = call_user_func(array($class_name, 'getInstance'), self::$plugin_config); 135 | try { 136 | if ($config['is_clean'] == '1') self::$cache->flush(); 137 | } catch (Exception $e) { 138 | print $e->getMessage(); 139 | die; 140 | } 141 | // 删除缓存仅生效一次 142 | $config['is_clean'] = '0'; 143 | } 144 | 145 | Helper::configPlugin('TpCache', $config); 146 | } 147 | 148 | /** 149 | * 个人用户的配置面板 150 | * 151 | * @access public 152 | * @param Typecho_Widget_Helper_Form $form 153 | * @return void 154 | */ 155 | public static function personalConfig(Typecho_Widget_Helper_Form $form) 156 | { 157 | } 158 | 159 | /** 160 | * 缓存前置操作 161 | */ 162 | public static function C() 163 | { 164 | $start = microtime(true); 165 | // 插件初始化 166 | if (!self::init()) return false; 167 | // 前置条件检查 168 | if (!self::pre_check()) return false; 169 | 170 | 171 | 172 | try { 173 | $data = self::get(self::$path); 174 | if ($data != false) { 175 | $data = unserialize($data); 176 | //如果超时 177 | if ($data['c_time'] + self::$plugin_config->expire <= time()) { 178 | 179 | if (self::$plugin_config->is_debug) echo "Expired!\n"; 180 | $data['c_time'] = $data['c_time'] + 20; 181 | self::set(self::$path, serialize($data)); 182 | } else { 183 | if (self::$plugin_config->is_debug) echo "Hit!\n"; 184 | if ($data['html']) echo $data['html']; 185 | $end = microtime(true); 186 | $time = number_format(($end - $start), 6); 187 | if (self::$plugin_config->is_debug) echo 'This page loaded in ', $time, ' seconds'; 188 | die; 189 | } 190 | } else { 191 | if (self::$plugin_config->is_debug) echo "Can't find cache!"; 192 | } 193 | 194 | } catch (Exception $e) { 195 | echo $e->getMessage(); 196 | } 197 | // 先进行一次刷新 198 | ob_flush(); 199 | 200 | } 201 | 202 | /** 203 | * 前置检查 204 | * @return bool 205 | */ 206 | public static function pre_check() 207 | { 208 | //对登录用户失效 209 | if (self::check_login()) return false; 210 | //针对POST失效 211 | if (self::$request->isPost()) return false; 212 | //是否支持SSL 213 | if (self::$plugin_config->enable_ssl == '0' && self::$request->isSecure() == true) return false; 214 | return true; 215 | } 216 | 217 | /** 218 | * 判断用户是否登录 219 | * @return bool 220 | * @throws Typecho_Widget_Exception 221 | */ 222 | public static function check_login() 223 | { 224 | //http与https相互独立 225 | return (self::$plugin_config->login && Typecho_Widget::widget('Widget_User')->hasLogin()); 226 | } 227 | 228 | /** 229 | * 根据配置判断是否需要缓存 230 | * @param string 路径信息 231 | * @return bool 232 | */ 233 | public static function needCache($path) 234 | { 235 | //后台数据不缓存 236 | $pattern = '#^' . __TYPECHO_ADMIN_DIR__ . '#i'; 237 | if (preg_match($pattern, $path)) return false; 238 | 239 | //action动作不缓存 240 | $pattern = '#^/action#i'; 241 | if (preg_match($pattern, $path)) return false; 242 | 243 | $_routingTable = self::$sys_config->routingTable; 244 | 245 | $exclude = array('_year', '_month', '_day', '_page'); 246 | 247 | foreach ($_routingTable[0] as $key => $route) { 248 | if ($route['widget'] != 'Widget_Archive') continue; 249 | 250 | if (preg_match($route['regx'], $path, $matches)) { 251 | $key = str_replace($exclude, '', str_replace($exclude, '', $key)); 252 | 253 | if (in_array($key, self::$plugin_config->cache_page)) { 254 | if (self::$plugin_config->is_debug) echo "This page needs to be cached!\n" . ' 255 | Bug Report '; 256 | self::$path = $path; 257 | return true; 258 | } 259 | } 260 | } 261 | 262 | return false; 263 | } 264 | 265 | 266 | /** 267 | * 缓存后置操作 268 | */ 269 | public static function S() 270 | { 271 | //对登录用户失效 272 | if (self::check_login()) return; 273 | 274 | //若self::$key不为空,则使用缓存 275 | if (is_null(self::$key)) return; 276 | 277 | 278 | $html = ob_get_contents(); 279 | 280 | if (!empty($html)) { 281 | $data = array(); 282 | $data['c_time'] = time(); 283 | $data['html'] = $html; 284 | //更新缓存 285 | if (self::$plugin_config->is_debug) echo "Cache updated!\n"; 286 | self::set(self::$key, serialize($data)); 287 | } 288 | 289 | } 290 | 291 | 292 | /** 293 | * 编辑文章后更新缓存 294 | * @param $contents 295 | * @param $class 296 | */ 297 | public static function post_update($contents, $class) 298 | { 299 | if ('publish' != $contents['visibility'] || $contents['created'] > time()) { 300 | return; 301 | } 302 | //获取系统配置 303 | $options = Helper::options(); 304 | 305 | if(!$options->plugin('TpCache')->cache_driver){ 306 | return; 307 | } 308 | //获取文章类型 309 | $type = $contents['type']; 310 | //获取路由信息 311 | $routeExists = (NULL != Typecho_Router::get($type)); 312 | 313 | if (!is_null($routeExists)) { 314 | $db = Typecho_Db::get(); 315 | $contents['cid'] = $class->cid; 316 | $contents['categories'] = $db->fetchAll($db->select()->from('table.metas') 317 | ->join('table.relationships', 'table.relationships.mid = table.metas.mid') 318 | ->where('table.relationships.cid = ?', $contents['cid']) 319 | ->where('table.metas.type = ?', 'category') 320 | ->order('table.metas.order', Typecho_Db::SORT_ASC)); 321 | $contents['category'] = urlencode(current(Typecho_Common::arrayFlatten($contents['categories'], 'slug'))); 322 | $contents['slug'] = urlencode($contents['slug']); 323 | $contents['date'] = new Typecho_Date($contents['created']); 324 | $contents['year'] = $contents['date']->year; 325 | $contents['month'] = $contents['date']->month; 326 | $contents['day'] = $contents['date']->day; 327 | } 328 | 329 | //生成永久连接 330 | $path_info = $routeExists ? Typecho_Router::url($type, $contents) : '#'; 331 | 332 | if (self::init($path_info)) self::delete($path_info); 333 | } 334 | 335 | /** 336 | * 评论更新 337 | * 338 | * @access public 339 | * @param array $comment 评论结构 340 | * @param Typecho_Widget $post 被评论的文章 341 | * @param array $result 返回的结果上下文 342 | * @param string $api api地址 343 | * @return void 344 | */ 345 | public static function comment_update($comment) 346 | { 347 | $req = new Typecho_Request(); 348 | // 获取评论的PATH_INFO 349 | $path_info = $req->getPathInfo(); 350 | // 删除最后的 /comment就是需删除的key 351 | $article_url = preg_replace('/\/comment$/i','',$path_info); 352 | 353 | self::init($article_url); 354 | 355 | self::delete($article_url); 356 | } 357 | 358 | /** 359 | * 插件配置初始化 360 | * @param $pathInfo 361 | * @return bool 362 | * @throws Typecho_Plugin_Exception 363 | */ 364 | public static function init($pathInfo='') 365 | { 366 | if (is_null(self::$sys_config)) { 367 | self::$sys_config = Helper::options(); 368 | } 369 | if (is_null(self::$plugin_config)) { 370 | self::$plugin_config = self::$sys_config->plugin('TpCache'); 371 | } 372 | 373 | if (self::$plugin_config->cache_driver == '0') { 374 | return false; 375 | } 376 | 377 | if(empty($pathInfo)){ 378 | 379 | if (is_null(self::$request)) { 380 | self::$request = new Typecho_Request(); 381 | } 382 | 383 | //获取路径信息 384 | $pathInfo = self::$request->getPathInfo(); 385 | 386 | } 387 | //判断是否需要缓存 388 | if (!self::needCache($pathInfo)) return false; 389 | 390 | self::init_driver(); 391 | 392 | return true; 393 | } 394 | 395 | /** 396 | * 插件驱动初始化 397 | * @return bool 398 | * @throws Typecho_Plugin_Exception 399 | */ 400 | public static function init_driver(){ 401 | if (is_null(self::$cache)) { 402 | $driver_name = self::$plugin_config->cache_driver; 403 | $class_name = "typecho_$driver_name"; 404 | $file_path = "driver/$class_name.class.php"; 405 | require_once 'driver/cache.interface.php'; 406 | require_once $file_path; 407 | self::$cache = call_user_func(array($class_name, 'getInstance'), self::$plugin_config); 408 | } 409 | } 410 | 411 | 412 | public static function set($path, $data) 413 | { 414 | 415 | if (!is_null(self::$key)) return self::$cache->set(self::$key, $data); 416 | $prefix = self::$request->getUrlPrefix(); 417 | self::$key = md5($prefix . $path); 418 | 419 | return self::$cache->set(self::$key, $data); 420 | } 421 | 422 | public static function add($path, $data) 423 | { 424 | 425 | } 426 | 427 | public static function get($path) 428 | { 429 | if (!is_null(self::$key)) return self::$cache->get(self::$key); 430 | $prefix = self::$request->getUrlPrefix(); 431 | self::$key = md5($prefix . $path); 432 | return self::$cache->get(self::$key); 433 | } 434 | 435 | /** 436 | * 删除指定路径 437 | * @param string $path 待删除路径 438 | * @param null $del_home 是否删除首页缓存 439 | */ 440 | public static function delete($path, $del_home = null) 441 | { 442 | $prefixs = array( 443 | 'http' 444 | . '://' . (isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : 445 | ($_SERVER['SERVER_NAME'] . (in_array($_SERVER['SERVER_PORT'], array(80, 443)) 446 | ? '' : ':' . $_SERVER['SERVER_PORT'])) 447 | ), 448 | 'https' 449 | . '://' . (isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : 450 | ($_SERVER['SERVER_NAME'] . (in_array($_SERVER['SERVER_PORT'], array(80, 443)) 451 | ? '' : ':' . $_SERVER['SERVER_PORT'])) 452 | ), 453 | ); 454 | $keys = array(); 455 | if (!is_array($path)) { 456 | $keys[] = $path; 457 | } else { 458 | $keys = $path; 459 | } 460 | 461 | 462 | foreach ($keys as $v) { 463 | foreach ($prefixs as $prefix) { 464 | echo $prefix . $v; 465 | @self::$cache->delete(md5($prefix . $v)); 466 | } 467 | } 468 | 469 | if (is_null($del_home)) { 470 | foreach ($prefixs as $prefix) { 471 | echo $prefix . '/'; 472 | @self::$cache->delete(md5($prefix . '/')); 473 | } 474 | } 475 | } 476 | } 477 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## 功能 2 | 3 | 减缓网站并发压力而开发的缓存插件。 4 | 5 | ## 注意 6 | 7 | 1. 支持**Memcache**,**Redis**,**Mysql**三种驱动。 8 | 1. **非js方式的**访问统计插件会失效 9 | 1. BUG请在[缓存插件TpCache for Typecho][1]页汇报 10 | 11 | 12 | 13 | 14 | 15 | ## 使用说明 16 | 17 | ### 后台设置 18 | 19 | ![后台设置截图][2] 20 | 21 | ### 组件支持 22 | 23 | **请确保你的服务器memcache套件工作正常。** 24 | 25 | 目前老高提供了php**memcache**与**memcached**的支持,请选择对应的驱动。 26 | 27 | memcached配置请参考[Linux服务器配置memcached并启用PHP支持][3]。 28 | 29 | Redis配置请参考[Linux服务器配置Redis并启用PHP支持][4]。 30 | 31 | ### 缓存更新机制 32 | 33 | **目前以下操作会触发缓存更新** 34 | 35 | - 来自原生评论系统的评论 36 | - 后台文章或页面更新 37 | - 重启memcached 38 | - 缓存到期 39 | 40 | ### 评论 41 | 42 | 原生评论简单测试过,没有大问题。 43 | 44 | 不过既然使用缓存了不如直接使用第三方评论系统,如多说。 45 | 46 | ## 性能 47 | 48 | 在老高的烂主机上随便就能跑到保守800的并发(CPU占用不到70%),什么概念呢? 49 | 50 | 理论上支持每天**69120000**(60\*60\*24\*800)的PV。 51 | 52 | ## 下载 53 | 54 | TpCache 55 | 56 | TpCache 57 | 58 | ## 安装 59 | 60 | 请将文件夹**重命名**为TpCache。再拷贝至`usr/plugins/下`。 61 | 62 | ## 升级 63 | 64 | 请先**禁用此插件**后再升级,很多莫名其妙的问题都是因为没有先禁用而直接升级导致的! 65 | 66 | 67 | [1]: http://www.phpgao.com/tpcache_for_typecho.html 68 | [2]: http://www.phpgao.com/usr/uploads/2015/05/3901966986.jpeg 69 | [3]: http://www.phpgao.com/php-memcached-extension-installation.html 70 | [4]: http://www.phpgao.com/redis_php.html -------------------------------------------------------------------------------- /driver/cache.interface.php: -------------------------------------------------------------------------------- 1 | host = $option->host; 15 | $this->port = $option->port; 16 | $this->expire = $option->expire; 17 | $this->init($option); 18 | } 19 | 20 | static public function getInstance($option) 21 | { 22 | if (is_null(self::$_instance) || isset (self::$_instance)) { 23 | self::$_instance = new self($option); 24 | } 25 | return self::$_instance; 26 | } 27 | 28 | public function init($option) 29 | { 30 | try { 31 | $this->mc = new Memcache; 32 | $this->mc->addServer($this->host, $this->port); 33 | } catch (Exception $e) { 34 | echo $e->getMessage(); 35 | } 36 | } 37 | 38 | public function add($key, $value, $expire = null) 39 | { 40 | return $this->mc->add($key, $value, false, is_null($expire) ? $this->expire : $expire); 41 | } 42 | 43 | public function delete($key) 44 | { 45 | return $this->mc->delete($key); 46 | } 47 | 48 | public function set($key, $value, $expire = null) 49 | { 50 | return $this->mc->set($key, $value, false, is_null($expire) ? $this->expire : $expire); 51 | } 52 | 53 | public function get($key) 54 | { 55 | return $this->mc->get($key); 56 | } 57 | 58 | public function flush() 59 | { 60 | return $this->mc->flush(); 61 | } 62 | } -------------------------------------------------------------------------------- /driver/typecho_memcached.class.php: -------------------------------------------------------------------------------- 1 | host = $option->host; 13 | $this->port = $option->port; 14 | $this->expire = $option->expire; 15 | $this->init($option); 16 | } 17 | 18 | static public function getInstance($option) { 19 | if (is_null ( self::$_instance ) || isset ( self::$_instance )) { 20 | self::$_instance = new self($option); 21 | } 22 | return self::$_instance; 23 | } 24 | 25 | public function init($option) 26 | { 27 | try{ 28 | $this->mc = new Memcached; 29 | $this->mc->addServer($this->host, $this->port); 30 | }catch (Exception $e){ 31 | echo $e->getMessage(); 32 | } 33 | } 34 | 35 | public function add($key, $value, $expire=null) 36 | { 37 | return $this->mc->add($key, $value, is_null($expire) ? $this->expire : $expire); 38 | } 39 | 40 | public function delete($key) 41 | { 42 | return $this->mc->delete($key); 43 | } 44 | 45 | public function set($key, $value, $expire=null) 46 | { 47 | return $this->mc->set($key, $value, is_null($expire) ? $this->expire : $expire); 48 | } 49 | 50 | public function get($key) 51 | { 52 | return $this->mc->get($key); 53 | } 54 | 55 | public function flush() 56 | { 57 | return $this->mc->flush(); 58 | } 59 | } -------------------------------------------------------------------------------- /driver/typecho_mysql.class.php: -------------------------------------------------------------------------------- 1 | host = $option->host; 16 | $this->port = $option->port; 17 | $this->expire = $option->expire; 18 | $this->init($option); 19 | } 20 | 21 | static public function getInstance($option) 22 | { 23 | if (is_null(self::$_instance) || isset (self::$_instance)) { 24 | self::$_instance = new self($option); 25 | } 26 | return self::$_instance; 27 | } 28 | 29 | public function init($option) 30 | { 31 | $this->db = Typecho_Db::get(); 32 | $prefix = $this->db->getPrefix(); 33 | $table_name = $prefix . 'cache'; 34 | $sql_detect = "SHOW TABLES LIKE '%" . $table_name . "%'"; 35 | 36 | if(count($this->db->fetchAll($sql_detect)) == 0){ 37 | $this->install_db(); 38 | }else{ 39 | // 用访问触发缓存过期 40 | $this->db->query($this->db->delete('table.cache')->where('time <= ?', (time() - $this->expire) )); 41 | } 42 | } 43 | 44 | public function install_db() 45 | { 46 | $install_sql = ' 47 | DROP TABLE IF EXISTS `%prefix%cache`; 48 | CREATE TABLE `%prefix%cache` ( 49 | `key` char(32) NOT NULL, 50 | `data` text, 51 | `time` bigint(20) DEFAULT NULL, 52 | PRIMARY KEY (`key`) 53 | ) ENGINE=MyISAM DEFAULT CHARSET=%charset%'; 54 | 55 | $prefix = $this->db->getPrefix(); 56 | $search = array('%prefix%', '%charset%'); 57 | $replace = array($prefix, str_replace('UTF-8', 'utf8', Helper::options()->charset)); 58 | $sql = str_replace($search, $replace, $install_sql); 59 | $sqls = explode(';', $sql); 60 | 61 | foreach ($sqls as $sql) { 62 | try{ 63 | $this->db->query($sql); 64 | }catch (Typecho_Db_Exception $e){ 65 | echo $e->getMessage(); 66 | } 67 | } 68 | } 69 | 70 | public function add($key, $value, $expire = null) 71 | { 72 | $this->db->query($this->db->insert('table.cache')->rows(array( 73 | 'key' => $key, 74 | 'data' => $value, 75 | 'time' => time() 76 | ))); 77 | } 78 | 79 | public function delete($key) 80 | { 81 | return $this->db->query($this->db->delete('table.cache')->where('key = ?', $key)); 82 | } 83 | 84 | public function set($key, $value, $expire = null) 85 | { 86 | $this->delete($key); 87 | $this->add($key, $value); 88 | } 89 | 90 | public function get($key) 91 | { 92 | $rs = $this->db->fetchRow($this->db->select('*')->from('table.cache')->where('key = ?', $key)); 93 | if(count($rs) == 0){ 94 | return false; 95 | }else{ 96 | return $rs['data']; 97 | } 98 | } 99 | 100 | public function flush() 101 | { 102 | return $this->db->query($this->db->delete('table.cache')); 103 | } 104 | } -------------------------------------------------------------------------------- /driver/typecho_redis.class.php: -------------------------------------------------------------------------------- 1 | host = $option->host; 13 | $this->port = $option->port; 14 | $this->expire = $option->expire + 0; 15 | $this->init($option); 16 | } 17 | 18 | static public function getInstance($option) { 19 | if (is_null ( self::$_instance ) || ! isset ( self::$_instance )) { 20 | self::$_instance = new self($option); 21 | } 22 | return self::$_instance; 23 | } 24 | 25 | public function init($option) 26 | { 27 | try{ 28 | $this->redis = new Redis(); 29 | $this->redis->connect($this->host, $this->port); 30 | }catch (Exception $e){ 31 | echo $e->getMessage(); 32 | } 33 | } 34 | 35 | public function add($key, $value, $expire=null) 36 | { 37 | return $this->redis->set($key, $value, is_null($expire) ? $this->expire : $expire); 38 | } 39 | 40 | public function delete($key) 41 | { 42 | return $this->redis->delete($key); 43 | } 44 | 45 | public function set($key, $value, $expire=null) 46 | { 47 | return $this->redis->set($key, $value, is_null($expire) ? $this->expire : $expire); 48 | } 49 | 50 | public function get($key) 51 | { 52 | return $this->redis->get($key); 53 | } 54 | 55 | public function flush() 56 | { 57 | return $this->redis->flushDB(); 58 | } 59 | } 60 | --------------------------------------------------------------------------------