config = C('redis'); if (empty($this->config['slave'])) $this->config['slave'] = $this->config['master']; $this->prefix = $this->config['prefix'] ? $this->config['prefix'] : substr(md5($_SERVER['HTTP_HOST']), 0, 6).'_'; if ( !extension_loaded('redis') ) { throw_exception('redis failed to load'); } $this->master = null; $this->slave = null; } public function __destruct() { if(defined('USE_COROUTINE') && USE_COROUTINE && defined('COROUTINE_HOOK_TCP') && COROUTINE_HOOK_TCP) { if(!CoRedisPool::instance()->stoped()) { $other = co_create_instance('Cache','connect',['cacheredis']); $other->attach($this->master,$this->slave); $this->master = null; $this->slave = null; CoRedisPool::instance()->put($other); } } } private function attach($master,$slave) { $this->master = $master; $this->slave = $slave; } private function init_master() { if(defined('USE_COROUTINE') && USE_COROUTINE && defined('COROUTINE_HOOK_TCP') && COROUTINE_HOOK_TCP) { if (!is_null($this->master)) { if($this->master->isConnected()) { $this->handler = $this->master; $this->enable = true; return; } else { $this->master->close(); Log::record("CacheRedis init_slave disconnect.",Log::DEBUG); } } if (is_mobile()) { $func = 'connect'; } else { $func = $this->config['pconnect'] ? 'pconnect' : 'connect'; } $this->master = new Redis(); $this->enable = $this->master->$func($this->config['master']['host'], $this->config['master']['port']); } else { static $_cache; if (isset($_cache)) { if($_cache->isConnected()) { $this->master = $_cache; $this->handler = $this->master; $this->enable = true; return; } else { $_cache->close(); Log::record("CacheRedis init_slave disconnect.",Log::DEBUG); } } if (is_mobile()) { $func = 'connect'; } else { $func = $this->config['pconnect'] ? 'pconnect' : 'connect'; } $this->master = new Redis(); $this->enable = $this->master->$func($this->config['master']['host'], $this->config['master']['port']); $_cache = $this->master; } $this->handler = $this->master; } private function init_slave() { if(defined('USE_COROUTINE') && USE_COROUTINE && defined('COROUTINE_HOOK_TCP') && COROUTINE_HOOK_TCP) { if (!is_null($this->slave)) { if($this->slave->isConnected()) { $this->handler = $this->slave; $this->enable = true; return; } else { $this->slave->close(); Log::record("CacheRedis init_slave disconnect.",Log::DEBUG); } } if (is_mobile()) { $func = 'connect'; } else { $func = $this->config['pconnect'] ? 'pconnect' : 'connect'; } $this->slave = new Redis(); $this->enable = $this->slave->$func($this->config['slave']['host'], $this->config['slave']['port']); } else { static $_cache; if (isset($_cache)) { if($_cache->isConnected()) { $this->slave = $_cache; $this->enable = true; return; } else { $_cache->close(); Log::record("CacheRedis init_slave disconnect.",Log::DEBUG); } } if (is_mobile()) { $func = 'connect'; } else { $func = $this->config['pconnect'] ? 'pconnect' : 'connect'; } $this->slave = new Redis(); $this->enable = $this->slave->$func($this->config['slave']['host'], $this->config['slave']['port']); $_cache = $this->slave; } $this->handler = $this->slave; } public function get($key, $prefix = '') { $this->init_slave(); if (!$this->enable) return false; $this->type = $prefix; $value = $this->handler->get($this->_key($key)); return unserialize($value); } public function set($key, $value, $prefix = '', $expire = null) { $this->init_master(); if (!$this->enable) return false; $this->type = $prefix; $value = serialize($value); if(is_int($expire)) { $result = $this->handler->setex($this->_key($key), $expire, $value); }else{ $result = $this->handler->set($this->_key($key), $value); } return $result; } public function set_org($key,$val,$prefix = '') { $this->init_master(); if (!$this->enable) return false; $this->type = $prefix; $result = $this->handler->set($this->_key($key), $val); return $result; } public function get_org($key,$prefix = '') { $this->init_slave(); if (!$this->enable) return false; $this->type = $prefix; $result = $this->handler->get($this->_key($key)); return $result; } public function incr($key,$prefix = '') { $this->init_master(); if (!$this->enable) return false; $this->type = $prefix; $key = $this->_key($key); $value = $this->handler->incr($key); return $value; } public function incrby($key,$val,$prefix = '') { $this->init_master(); if (!$this->enable) return false; $this->type = $prefix; $key = $this->_key($key); $value = $this->handler->incrby($key,$val); return $value; } public function decr($key,$prefix = '') { $this->init_master(); if (!$this->enable) return false; $this->type = $prefix; $key = $this->_key($key); $value = $this->handler->decr($key); return $value; } public function decrby($key,$val,$prefix = '') { $this->init_master(); if (!$this->enable) return false; $this->type = $prefix; $key = $this->_key($key); $value = $this->handler->decrby($key,$val); return $value; } public function zIncrBy($key, $value, $member,$prefix='') { $this->init_master(); if (!$this->enable) return false; $this->type = $prefix; $key = $this->_key($key); $result = $this->handler->zIncrBy($key,$value,$member); return $result; } public function zDelete($key, $member,$prefix='') { $this->init_master(); if (!$this->enable) return false; $this->type = $prefix; $key = $this->_key($key); $result = $this->handler->zDelete($key,$member); return $result; } public function hset($name, $prefix, $data) { $this->init_master(); if (!$this->enable || !is_array($data) || empty($data)) return false; $this->type = $prefix; foreach ($data as $key => $value) { if ($value[0] == 'exp') { $value[1] = str_replace(' ', '', $value[1]); preg_match('/^[A-Za-z_]+([+-]\d+(\.\d+)?)$/',$value[1],$matches); if (is_numeric($matches[1])) { $this->hIncrByFloat($name, $prefix, $key, $matches[1]); } unset($data[$key]); } } if (count($data) == 1) { $this->handler->hset($this->_key($name), key($data),current($data)); } elseif (count($data) > 1) { $this->handler->hMset($this->_key($name), $data); } } public function hget($name, $prefix, $key = null) { $this->init_slave(); if (!$this->enable) return false; $this->type = $prefix; if ($key == '*' || is_null($key)) { return $this->handler->hGetAll($this->_key($name)); } elseif (strpos($key,',') != false) { return $this->handler->hmGet($this->_key($name), explode(',',$key)); } else { return $this->handler->hGet($this->_key($name), $key); } } public function hdel($name, $prefix, $key = null) { $this->init_master(); if (!$this->enable) return false; $this->type = $prefix; if (is_null($key)) { if (is_array($name)) { return $this->handler->del(array_walk($array, [__CLASS__, '_key'])); } else { return $this->handler->del($this->_key($name)); } } elseif (is_array($name)) { foreach ($name as $key => $value) { $this->handler->hdel($this->_key($name), $key); } return true; } else { return $this->handler->hdel($this->_key($name), $key); } } public function hIncrBy($name, $key, $value) { $this->init_master(); if (!$this->enable) return false; $this->type = ''; return $this->handler->hIncrBy($this->_key($name), $key, $value); } public function hIncrByFloat($name, $prefix, $key, $num = 1) { $this->init_master(); if ($this->hget($name, $prefix,$key) !== false) { $this->handler->hIncrByFloat($this->_key($name), $key, floatval($num)); } } public function rm($key, $type = '') { $this->init_master(); if (!$this->enable) return false; $this->type = $type; return $this->handler->del($this->_key($key)); } public function clear() { $this->init_master(); if (!$this->enable) return false; return $this->handler->flushDB(); } private function _key($str) { return $this->prefix.$this->type.$str; } public function keys($key = '') { $this->init_slave(); if(!isset($key) || empty($key)) { $key = '*'; } return $this->handler->keys($this->_key($key)); } public function del($key){ $this->init_master(); if (!$this->enable) return false; return $this->handler->del($key); } public function lLen($key) { $this->init_slave(); if (!$this->enable) return false; return $this->handler->lLen($key); } public function lpush($queue_name,$value) { $this->init_master(); if (!$this->enable) return false; return $this->handler->lPush($queue_name, $value); } }