2017-04-23 11:20:32 +00:00
|
|
|
<?php
|
|
|
|
namespace devilbox;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @requires devilbox::Logger
|
|
|
|
*/
|
2017-05-15 06:56:17 +00:00
|
|
|
class Redis extends BaseClass implements BaseInterface
|
2017-04-23 11:20:32 +00:00
|
|
|
{
|
|
|
|
/*********************************************************************************
|
|
|
|
*
|
|
|
|
* Private Variables
|
|
|
|
*
|
|
|
|
*********************************************************************************/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Redis instance
|
|
|
|
* @var object|null
|
|
|
|
*/
|
|
|
|
private $_redis = null;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*********************************************************************************
|
|
|
|
*
|
2017-05-15 06:56:17 +00:00
|
|
|
* Constructor Overwrite
|
2017-04-23 11:20:32 +00:00
|
|
|
*
|
|
|
|
*********************************************************************************/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Use singleton getInstance() instead.
|
|
|
|
*
|
|
|
|
* @param string $user Username
|
|
|
|
* @param string $pass Password
|
|
|
|
* @param string $host Host
|
|
|
|
*/
|
2017-05-15 06:56:17 +00:00
|
|
|
public function __construct($hostname, $data = array())
|
2017-04-23 11:20:32 +00:00
|
|
|
{
|
2017-05-15 06:56:17 +00:00
|
|
|
parent::__construct($hostname, $data);
|
|
|
|
|
2018-04-08 10:18:44 +00:00
|
|
|
if ($this->isAvailable()) {
|
|
|
|
$redis = new \Redis();
|
|
|
|
if (!@$redis->connect($hostname, 6379, 0.5, NULL)) {
|
|
|
|
$this->setConnectError('Failed to connect to Redis host on '.$hostname);
|
|
|
|
$this->setConnectErrno(1);
|
|
|
|
//loadClass('Logger')->error($this->_connect_error);
|
|
|
|
} else {
|
2018-08-11 11:50:21 +00:00
|
|
|
if (array_key_exists('pass', $data)) {
|
2018-07-05 21:50:24 +00:00
|
|
|
$redis->auth($data['pass']);
|
|
|
|
}
|
2018-12-10 19:09:09 +00:00
|
|
|
$redis->set('devilbox-version', $GLOBALS['DEVILBOX_VERSION'].' ('.$GLOBALS['DEVILBOX_DATE'].')');
|
2018-04-08 10:18:44 +00:00
|
|
|
$this->_redis = $redis;
|
|
|
|
}
|
2017-04-23 11:20:32 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Destructor
|
|
|
|
*/
|
|
|
|
public function __destruct()
|
|
|
|
{
|
|
|
|
if ($this->_redis) {
|
|
|
|
$this->_redis->close();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-05-06 09:13:33 +00:00
|
|
|
|
|
|
|
|
2017-04-23 11:20:32 +00:00
|
|
|
/*********************************************************************************
|
|
|
|
*
|
2017-05-15 06:56:17 +00:00
|
|
|
* Select functions
|
2017-04-23 11:20:32 +00:00
|
|
|
*
|
|
|
|
*********************************************************************************/
|
2018-12-10 12:55:01 +00:00
|
|
|
public function flushDB($db)
|
|
|
|
{
|
|
|
|
if ($this->_redis) {
|
|
|
|
if ( !$this->_redis->select($db) ) {
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
return $this->_redis->flushDb();
|
|
|
|
} else {
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
2017-04-23 11:20:32 +00:00
|
|
|
|
2017-04-23 11:34:14 +00:00
|
|
|
public function getInfo()
|
|
|
|
{
|
2017-05-06 09:13:33 +00:00
|
|
|
if ($this->_redis) {
|
|
|
|
return $this->_redis->info('all');
|
|
|
|
} else {
|
|
|
|
return array();
|
|
|
|
}
|
2017-04-23 11:34:14 +00:00
|
|
|
}
|
2017-04-23 11:20:32 +00:00
|
|
|
|
2018-08-12 08:26:51 +00:00
|
|
|
public function getDatabases()
|
|
|
|
{
|
|
|
|
$databases = array();
|
|
|
|
|
|
|
|
foreach ($this->getInfo() as $key => $val) {
|
|
|
|
if (preg_match('/db[0-9]+/', $key)) {
|
|
|
|
$databases[] = str_replace('db', '', $key);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return ($databases);
|
|
|
|
}
|
|
|
|
|
2017-04-23 12:08:54 +00:00
|
|
|
public function getKeys()
|
|
|
|
{
|
2017-05-07 16:49:38 +00:00
|
|
|
$store = array();
|
2017-05-06 09:13:33 +00:00
|
|
|
if ($this->_redis) {
|
2018-08-12 08:26:51 +00:00
|
|
|
$databases = $this->getDatabases();
|
|
|
|
foreach ($databases as $db) {
|
|
|
|
$this->_redis->select($db);
|
|
|
|
$keys = $this->_redis->keys('*');
|
|
|
|
foreach ($keys as $key) {
|
2018-12-10 12:55:01 +00:00
|
|
|
|
|
|
|
switch($this->_redis->type($key)) {
|
|
|
|
case \Redis::REDIS_STRING:
|
|
|
|
$dtype = 'string';
|
|
|
|
break;
|
|
|
|
case \Redis::REDIS_SET:
|
|
|
|
$dtype = 'set';
|
|
|
|
break;
|
|
|
|
case \Redis::REDIS_LIST:
|
|
|
|
$dtype = 'list';
|
|
|
|
break;
|
|
|
|
case \Redis::REDIS_ZSET:
|
|
|
|
$dtype = 'zset';
|
|
|
|
break;
|
|
|
|
case \Redis::REDIS_HASH:
|
|
|
|
$dtype = 'hash';
|
|
|
|
break;
|
|
|
|
case \Redis::REDIS_NOT_FOUND:
|
|
|
|
$dtype = 'other';
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
$dtype = 'unknown';
|
|
|
|
}
|
|
|
|
$store[$db][] = array(
|
|
|
|
'name' => $key,
|
|
|
|
'val' => $this->_redis->get($key),
|
|
|
|
'type' => $dtype,
|
|
|
|
'ttl' => $this->_redis->ttl($key)
|
|
|
|
);
|
2018-08-12 08:26:51 +00:00
|
|
|
}
|
2017-05-07 16:49:38 +00:00
|
|
|
}
|
2017-05-06 09:13:33 +00:00
|
|
|
}
|
2017-05-07 16:49:38 +00:00
|
|
|
return $store;
|
2017-04-23 12:08:54 +00:00
|
|
|
}
|
|
|
|
|
2017-04-23 11:20:32 +00:00
|
|
|
|
2017-05-06 09:13:33 +00:00
|
|
|
|
2017-04-23 11:20:32 +00:00
|
|
|
/*********************************************************************************
|
|
|
|
*
|
2017-05-06 09:13:33 +00:00
|
|
|
* Interface required functions
|
2017-04-23 11:20:32 +00:00
|
|
|
*
|
|
|
|
*********************************************************************************/
|
|
|
|
|
2017-05-15 06:56:17 +00:00
|
|
|
private $_can_connect = array();
|
|
|
|
private $_can_connect_err = array();
|
|
|
|
|
|
|
|
private $_name = null;
|
|
|
|
private $_version = null;
|
|
|
|
|
|
|
|
public function canConnect(&$err, $hostname, $data = array())
|
|
|
|
{
|
|
|
|
$err = false;
|
|
|
|
|
|
|
|
// Return if already cached
|
|
|
|
if (isset($this->_can_connect[$hostname])) {
|
|
|
|
// Assume error for unset error message
|
|
|
|
$err = isset($this->_can_connect_err[$hostname]) ? $this->_can_connect_err[$hostname] : true;
|
|
|
|
return $this->_can_connect[$hostname];
|
|
|
|
}
|
|
|
|
|
|
|
|
// Silence errors and try to connect
|
|
|
|
//error_reporting(0);
|
|
|
|
$redis = new \Redis();
|
|
|
|
|
|
|
|
if (!$redis->connect($hostname, 6379)) {
|
|
|
|
$err = 'Failed to connect to Redis host on '.$hostname;
|
|
|
|
$this->_can_connect[$hostname] = false;
|
|
|
|
} else {
|
|
|
|
$this->_can_connect[$hostname] = true;
|
|
|
|
}
|
|
|
|
//error_reporting(-1);
|
|
|
|
|
|
|
|
$redis->close();
|
|
|
|
|
|
|
|
$this->_can_connect_err[$hostname] = $err;
|
|
|
|
return $this->_can_connect[$hostname];
|
|
|
|
}
|
|
|
|
|
2017-05-06 09:13:33 +00:00
|
|
|
public function getName($default = 'Redis')
|
2017-04-23 11:20:32 +00:00
|
|
|
{
|
2017-05-06 09:13:33 +00:00
|
|
|
return $default;
|
2017-04-23 11:20:32 +00:00
|
|
|
}
|
|
|
|
|
2017-05-06 09:13:33 +00:00
|
|
|
public function getVersion()
|
2017-04-23 11:20:32 +00:00
|
|
|
{
|
2017-05-15 06:56:17 +00:00
|
|
|
// Return if already cached
|
|
|
|
if ($this->_version !== null) {
|
|
|
|
return $this->_version;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Return empty if not available
|
|
|
|
if (!$this->isAvailable()) {
|
|
|
|
$this->_version = '';
|
|
|
|
return $this->_version;
|
|
|
|
}
|
|
|
|
|
2017-05-06 09:13:33 +00:00
|
|
|
$info = $this->getInfo();
|
|
|
|
if (!isset($info['redis_version'])) {
|
|
|
|
loadClass('Logger')->error('Could not get Redis version');
|
2017-05-15 06:56:17 +00:00
|
|
|
$this->_version = '';
|
|
|
|
} else {
|
|
|
|
$this->_version = $info['redis_version'];
|
2017-05-06 09:13:33 +00:00
|
|
|
}
|
2017-05-15 06:56:17 +00:00
|
|
|
|
|
|
|
return $this->_version;
|
2017-04-23 11:20:32 +00:00
|
|
|
}
|
|
|
|
}
|