2017-05-06 09:13:33 +00:00
|
|
|
<?php
|
|
|
|
namespace devilbox;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @requires devilbox::Logger
|
|
|
|
*/
|
|
|
|
class Memcd extends _Base implements _iBase
|
|
|
|
{
|
|
|
|
|
|
|
|
/*********************************************************************************
|
|
|
|
*
|
|
|
|
* Statics
|
|
|
|
*
|
|
|
|
*********************************************************************************/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Memcached instance
|
|
|
|
* @var Memcached|null
|
|
|
|
*/
|
|
|
|
protected static $instance = null;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Singleton Instance getter.
|
|
|
|
*
|
|
|
|
* @param string $user Username
|
|
|
|
* @param string $pass Password
|
|
|
|
* @param string $host Host
|
|
|
|
* @return object|null
|
|
|
|
*/
|
|
|
|
public static function getInstance($host, $user = null, $pass = null)
|
|
|
|
{
|
|
|
|
if (!isset(static::$instance)) {
|
|
|
|
static::$instance = new static($host);
|
|
|
|
}
|
|
|
|
// If current Memcached instance was unable to connect
|
|
|
|
if (!static::$instance) {
|
|
|
|
//loadClass('Logger')->error('Instance has errors:' . "\r\n" . var_export(static::$instance, true) . "\r\n");
|
|
|
|
}
|
|
|
|
return static::$instance;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Connect to Memcached
|
|
|
|
*
|
|
|
|
* @param string $err Reference to error message
|
|
|
|
* @param string $host Memcached hostname
|
|
|
|
* @return boolean
|
|
|
|
*/
|
|
|
|
public static function testConnection(&$err, $host, $user = '', $pass = '')
|
|
|
|
{
|
|
|
|
$err = false;
|
|
|
|
|
|
|
|
// Silence errors and try to connect
|
|
|
|
//error_reporting(-1);
|
|
|
|
$memcd = new \Memcached();
|
|
|
|
$memcd->resetServerList();
|
|
|
|
|
|
|
|
|
|
|
|
if (!$memcd->addServer($host, 11211)) {
|
|
|
|
$memcd->quit();
|
|
|
|
$err = 'Failed to connect to Memcached host on '.$host;
|
|
|
|
error_reporting(-1);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
$stats = $memcd->getStats();
|
|
|
|
if (!isset($stats[$host.':11211'])) {
|
|
|
|
$memcd->quit();
|
|
|
|
$err = 'Failed to connect to Memcached host on '.$host;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (!isset($stats[$host.':11211']['pid'])) {
|
|
|
|
$memcd->quit();
|
|
|
|
$err = 'Failed to connect to Memcached host on '.$host;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if ($stats[$host.':11211']['pid'] < 1) {
|
|
|
|
$memcd->quit();
|
|
|
|
$err = 'Failed to connect to Memcached host on '.$host;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
$memcd->quit();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*********************************************************************************
|
|
|
|
*
|
|
|
|
* Private Variables
|
|
|
|
*
|
|
|
|
*********************************************************************************/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Memcached instance
|
|
|
|
* @var object|null
|
|
|
|
*/
|
|
|
|
private $_memcached = null;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*********************************************************************************
|
|
|
|
*
|
|
|
|
* Construct/Destructor
|
|
|
|
*
|
|
|
|
*********************************************************************************/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Use singleton getInstance() instead.
|
|
|
|
*
|
|
|
|
* @param string $user Username
|
|
|
|
* @param string $pass Password
|
|
|
|
* @param string $host Host
|
|
|
|
*/
|
|
|
|
public function __construct($host)
|
|
|
|
{
|
2017-05-07 16:49:38 +00:00
|
|
|
$memcd = new \Memcached('_devilbox');
|
|
|
|
$list = $memcd->getServerList();
|
|
|
|
|
2017-05-10 19:24:42 +00:00
|
|
|
// if (!empty($list)) {
|
|
|
|
// $memcd->resetServerList();
|
|
|
|
// }
|
2017-05-07 16:49:38 +00:00
|
|
|
if (empty($list)) {
|
2017-05-10 19:24:42 +00:00
|
|
|
//$memcd->setOption(\Memcached::OPT_RECV_TIMEOUT, 100);
|
|
|
|
//$memcd->setOption(\Memcached::OPT_SEND_TIMEOUT, 100);
|
2017-05-07 16:49:38 +00:00
|
|
|
$memcd->setOption(\Memcached::OPT_LIBKETAMA_COMPATIBLE, true);
|
|
|
|
$memcd->setOption(\Memcached::OPT_BINARY_PROTOCOL, false);
|
|
|
|
//$memcd->setOption(\Memcached::OPT_SERVER_FAILURE_LIMIT, 50);
|
2017-05-10 19:24:42 +00:00
|
|
|
//$memcd->setOption(\Memcached::OPT_CONNECT_TIMEOUT, 100);
|
|
|
|
//$memcd->setOption(\Memcached::OPT_RETRY_TIMEOUT, 100);
|
2017-05-07 16:49:38 +00:00
|
|
|
//$memcd->setOption(\Memcached::OPT_REMOVE_FAILED_SERVERS, true);
|
|
|
|
$memcd->addServer($host, 11211);
|
|
|
|
}
|
2017-05-06 09:13:33 +00:00
|
|
|
|
2017-05-07 16:49:38 +00:00
|
|
|
$err = false;
|
|
|
|
$stats = $memcd->getStats();
|
|
|
|
if (!isset($stats[$host.':11211'])) {
|
|
|
|
$memcd->quit();
|
|
|
|
$err = 'Failed to connect to Memcached host on '.$host;
|
|
|
|
}
|
2017-05-10 19:24:42 +00:00
|
|
|
else if (!isset($stats[$host.':11211']['pid'])) {
|
2017-05-07 16:49:38 +00:00
|
|
|
$memcd->quit();
|
|
|
|
$err = 'Failed to connect to Memcached host on '.$host;
|
|
|
|
}
|
2017-05-10 19:24:42 +00:00
|
|
|
else if ($stats[$host.':11211']['pid'] < 1) {
|
2017-05-07 16:49:38 +00:00
|
|
|
$memcd->quit();
|
|
|
|
$err = 'Failed to connect to Memcached host on '.$host;
|
|
|
|
}
|
|
|
|
|
2017-05-10 19:24:42 +00:00
|
|
|
else if ($err === false) {
|
2017-05-07 16:49:38 +00:00
|
|
|
$memcd->set('devilbox-version', $GLOBALS['DEVILBOX_VERSION'].' ('.$GLOBALS['DEVILBOX_DATE'].')');
|
|
|
|
$this->_memcached = $memcd;
|
|
|
|
} else {
|
2017-05-06 09:13:33 +00:00
|
|
|
$this->_connect_error = 'Failed to connect to Memcached host on '.$host;
|
|
|
|
$this->_connect_errno = 1;
|
|
|
|
//loadClass('Logger')->error($this->_connect_error);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Destructor
|
|
|
|
*/
|
|
|
|
public function __destruct()
|
|
|
|
{
|
|
|
|
if ($this->_memcached) {
|
|
|
|
$this->_memcached->quit();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*********************************************************************************
|
|
|
|
*
|
|
|
|
* Memcached Select functions
|
|
|
|
*
|
|
|
|
*********************************************************************************/
|
|
|
|
|
2017-05-07 16:49:38 +00:00
|
|
|
|
|
|
|
public function getKeys()
|
2017-05-06 09:13:33 +00:00
|
|
|
{
|
2017-05-07 16:49:38 +00:00
|
|
|
$store = array();
|
2017-05-06 09:13:33 +00:00
|
|
|
if ($this->_memcached) {
|
2017-05-07 16:49:38 +00:00
|
|
|
if (!($keys = $this->_memcached->getAllKeys())) {
|
|
|
|
$keys = array();
|
|
|
|
}
|
|
|
|
$this->_memcached->getDelayed($keys);
|
|
|
|
$store = $this->_memcached->fetchAll();
|
2017-05-06 09:13:33 +00:00
|
|
|
}
|
2017-05-07 16:49:38 +00:00
|
|
|
return $store;
|
2017-05-06 09:13:33 +00:00
|
|
|
}
|
|
|
|
|
2017-05-07 16:49:38 +00:00
|
|
|
public function getInfo()
|
2017-05-06 09:13:33 +00:00
|
|
|
{
|
2017-05-08 07:22:10 +00:00
|
|
|
$stats = array();
|
|
|
|
if ($this->_memcached) {
|
|
|
|
$stats = $this->_memcached->getStats();
|
|
|
|
}
|
2017-05-07 16:49:38 +00:00
|
|
|
return $stats;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2017-05-06 09:13:33 +00:00
|
|
|
|
|
|
|
/*********************************************************************************
|
|
|
|
*
|
|
|
|
* Interface required functions
|
|
|
|
*
|
|
|
|
*********************************************************************************/
|
|
|
|
|
|
|
|
public function getName($default = 'Memcached')
|
|
|
|
{
|
|
|
|
return $default;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getVersion()
|
|
|
|
{
|
2017-05-08 07:22:10 +00:00
|
|
|
$version = '';
|
|
|
|
if ($this->_memcached) {
|
|
|
|
$info = $this->_memcached->getVersion();
|
|
|
|
$info = array_values($info);
|
|
|
|
if (!isset($info[0])) {
|
|
|
|
loadClass('Logger')->error('Could not get Memcached version');
|
|
|
|
} else {
|
|
|
|
$version = $info[0];
|
|
|
|
}
|
2017-05-06 09:13:33 +00:00
|
|
|
}
|
2017-05-08 07:22:10 +00:00
|
|
|
|
|
|
|
return $version;
|
2017-05-06 09:13:33 +00:00
|
|
|
}
|
|
|
|
}
|