/** * Close * * Releases locks and closes connection. * * @return bool */ public function close() { if (isset($this->_redis)) { try { if ($this->_redis->ping() === '+PONG') { isset($this->_lock_key) && $this->_redis->delete($this->_lock_key); if (!$this->_redis->close()) { return FALSE; } } } catch (RedisException $e) { } $this->_redis = NULL; return TRUE; } return TRUE; }
/** * Close * * Releases locks and closes connection. * * @return bool */ public function close() { if (isset($this->_redis)) { try { if ($this->_redis->ping() === '+PONG') { isset($this->_lock_key) && $this->_redis->delete($this->_lock_key); if (!$this->_redis->close()) { return $this->_failure; } } } catch (RedisException $e) { log_message('error', 'Session: Got RedisException on close(): ' . $e->getMessage()); } $this->_redis = NULL; return $this->_success; } return $this->_success; }
/** * Close * * Releases locks and closes connection. * * @return bool */ public function close() { if (isset($this->_redis)) { try { if ($this->_redis->ping() === '+PONG') { $this->_release_lock(); if ($this->_redis->close() === FALSE) { return $this->_fail(); } } } catch (RedisException $e) { log_message('error', 'Session: Got RedisException on close(): ' . $e->getMessage()); } $this->_redis = NULL; return $this->_success; } return $this->_success; }
/** * Close * * Releases locks and closes connection. * * @return bool */ public function close() { if (isset($this->redis)) { try { if ($this->redis->ping() === '+PONG') { isset($this->lockKey) && $this->redis->delete($this->lockKey); if (!$this->redis->close()) { return FALSE; } } } catch (\RedisException $e) { $this->logger->error('Session: Got RedisException on close(): ' . $e->getMessage()); } $this->redis = NULL; return TRUE; } return TRUE; }
public function __call($name, $args) { // Lazy connection $this->connect(); $name = strtolower($name); // Send request via native PHP if ($this->standalone) { switch ($name) { case 'eval': case 'evalsha': $script = array_shift($args); $keys = (array) array_shift($args); $eArgs = (array) array_shift($args); $args = array($script, count($keys), $keys, $eArgs); break; case 'set': // The php redis module has different behaviour with ttl // https://github.com/phpredis/phpredis#set if (count($args) === 3 && is_int($args[2])) { $args = array($args[0], $args[1], array('EX', $args[2])); } elseif (count($args) === 3 && is_array($args[2])) { $tmp_args = $args; $args = array($tmp_args[0], $tmp_args[1]); foreach ($tmp_args[2] as $k => $v) { if (is_string($k)) { $args[] = array($k, $v); } elseif (is_int($k)) { $args[] = $v; } } unset($tmp_args); } break; case 'scan': case 'sscan': case 'hscan': case 'zscan': $ref =& $args[0]; if (empty($ref)) { $ref = 0; } $eArgs = array($ref); if (!empty($args[1])) { $eArgs[] = 'MATCH'; $eArgs[] = $args[1]; } if (!empty($args[2])) { $eArgs[] = 'COUNT'; $eArgs[] = $args[2]; } $args = $eArgs; break; case 'zrangebyscore': if (isset($args[3]) && is_array($args[3])) { // map options $cArgs = array(); if (!empty($args[3]['withscores'])) { $cArgs[] = 'withscores'; } if (array_key_exists('limit', $args[3])) { $cArgs[] = array('limit' => $args[3]['limit']); } $args[3] = $cArgs; } break; } // Flatten arguments $args = self::_flattenArguments($args); // In pipeline mode if ($this->usePipeline) { if ($name == 'pipeline') { throw new CredisException('A pipeline is already in use and only one pipeline is supported.'); } else { if ($name == 'exec') { if ($this->isMulti) { $this->commandNames[] = $name; $this->commands .= self::_prepare_command(array($this->getRenamedCommand($name))); } // Write request if ($this->commands) { $this->write_command($this->commands); } $this->commands = NULL; // Read response $response = array(); foreach ($this->commandNames as $command) { $response[] = $this->read_reply($command); } $this->commandNames = NULL; if ($this->isMulti) { $response = array_pop($response); } $this->usePipeline = $this->isMulti = FALSE; return $response; } else { if ($name == 'multi') { $this->isMulti = TRUE; } array_unshift($args, $this->getRenamedCommand($name)); $this->commandNames[] = $name; $this->commands .= self::_prepare_command($args); return $this; } } } // Start pipeline mode if ($name == 'pipeline') { $this->usePipeline = TRUE; $this->commandNames = array(); $this->commands = ''; return $this; } // If unwatching, allow reconnect with no error thrown if ($name == 'unwatch') { $this->isWatching = FALSE; } // Non-pipeline mode array_unshift($args, $this->getRenamedCommand($name)); $command = self::_prepare_command($args); $this->write_command($command); $response = $this->read_reply($name); switch ($name) { case 'scan': case 'sscan': case 'hscan': case 'zscan': $ref = array_shift($response); if (empty($ref)) { $response = false; } break; case 'zrangebyscore': if (in_array('withscores', $args, true)) { // Map array of values into key=>score list like phpRedis does $item = null; $out = array(); foreach ($response as $value) { if ($item == null) { $item = $value; } else { // 2nd value is the score $out[$item] = (double) $value; $item = null; } } $response = $out; } break; } // Watch mode disables reconnect so error is thrown if ($name == 'watch') { $this->isWatching = TRUE; } else { if ($this->isMulti && ($name == 'exec' || $name == 'discard')) { $this->isMulti = FALSE; } else { if ($this->isMulti || $name == 'multi') { $this->isMulti = TRUE; $response = $this; } } } } else { // Tweak arguments switch ($name) { case 'get': // optimize common cases // optimize common cases case 'set': case 'hget': case 'hset': case 'setex': case 'mset': case 'msetnx': case 'hmset': case 'hmget': case 'del': case 'zrangebyscore': break; case 'mget': if (isset($args[0]) && !is_array($args[0])) { $args = array($args); } break; case 'lrem': $args = array($args[0], $args[2], $args[1]); break; case 'eval': case 'evalsha': if (isset($args[1]) && is_array($args[1])) { $cKeys = $args[1]; } elseif (isset($args[1]) && is_string($args[1])) { $cKeys = array($args[1]); } else { $cKeys = array(); } if (isset($args[2]) && is_array($args[2])) { $cArgs = $args[2]; } elseif (isset($args[2]) && is_string($args[2])) { $cArgs = array($args[2]); } else { $cArgs = array(); } $args = array($args[0], array_merge($cKeys, $cArgs), count($cKeys)); break; case 'subscribe': case 'psubscribe': break; case 'scan': case 'sscan': case 'hscan': case 'zscan': // allow phpredis to see the caller's reference //$param_ref =& $args[0]; break; default: // Flatten arguments $args = self::_flattenArguments($args); } try { // Proxy pipeline mode to the phpredis library if ($name == 'pipeline' || $name == 'multi') { if ($this->isMulti) { return $this; } else { $this->isMulti = TRUE; $this->redisMulti = call_user_func_array(array($this->redis, $name), $args); } } else { if ($name == 'exec' || $name == 'discard') { $this->isMulti = FALSE; $response = $this->redisMulti->{$name}(); $this->redisMulti = NULL; #echo "> $name : ".substr(print_r($response, TRUE),0,100)."\n"; return $response; } } // Use aliases to be compatible with phpredis wrapper if (isset($this->wrapperMethods[$name])) { $name = $this->wrapperMethods[$name]; } // Multi and pipeline return self for chaining if ($this->isMulti) { call_user_func_array(array($this->redisMulti, $name), $args); return $this; } // Send request, retry one time when using persistent connections on the first request only $this->requests++; try { $response = call_user_func_array(array($this->redis, $name), $args); } catch (RedisException $e) { if ($this->persistent && $this->requests == 1 && $e->getMessage() == 'read error on connection') { $this->connected = FALSE; $this->connect(); $response = call_user_func_array(array($this->redis, $name), $args); } else { throw $e; } } } catch (RedisException $e) { $code = 0; if (!($result = $this->redis->ping())) { $this->connected = FALSE; $code = CredisException::CODE_DISCONNECTED; } throw new CredisException($e->getMessage(), $code, $e); } #echo "> $name : ".substr(print_r($response, TRUE),0,100)."\n"; // change return values where it is too difficult to minim in standalone mode switch ($name) { case 'hmget': $response = array_values($response); break; case 'type': $typeMap = array(self::TYPE_NONE, self::TYPE_STRING, self::TYPE_SET, self::TYPE_LIST, self::TYPE_ZSET, self::TYPE_HASH); $response = $typeMap[$response]; break; // Handle scripting errors // Handle scripting errors case 'eval': case 'evalsha': case 'script': $error = $this->redis->getLastError(); $this->redis->clearLastError(); if ($error && substr($error, 0, 8) == 'NOSCRIPT') { $response = NULL; } else { if ($error) { throw new CredisException($error); } } break; default: $error = $this->redis->getLastError(); $this->redis->clearLastError(); if ($error) { throw new CredisException($error); } break; } } return $response; }