288 lines
8.5 KiB
PHP
288 lines
8.5 KiB
PHP
<?php
|
|
use Predis\Collection\Iterator;
|
|
|
|
class CacheRedis
|
|
{
|
|
|
|
/*
|
|
* remember to add a definition for the 4 following parameters in settings.inc.php
|
|
define('_REDIS_AUTH_STRING_','')
|
|
define('_REDIS_HOST_STRING_','127.0.0.1')
|
|
define('_REDIS_PORT_STRING_','6379')
|
|
define('_REDIS_DEFAULT_TTL_','60')
|
|
|
|
* remember to add this line in defines.inc.php
|
|
define('_PS_PREDIS_DIR_', _PS_TOOL_DIR_.'predis/')
|
|
|
|
* autoload call to should be in autoload.php
|
|
|
|
*/
|
|
|
|
protected static $_instance;
|
|
|
|
private $auth;
|
|
private $port;
|
|
private $host;
|
|
private $db;
|
|
private $redis_client;
|
|
private $default_ttl;
|
|
private $short_ttl;
|
|
private $medium_ttl;
|
|
private $long_ttl;
|
|
private $is_connected = false;
|
|
const DEFAULT_CONTROLLER_NAME = "none";
|
|
const HASHING_ALGORITHM = "sha1";
|
|
|
|
const SHORT_TTL = '_REDIS_SHORT_TTL_';
|
|
const MEDIUM_TTL = '_REDIS_MEDIUM_TTL_';
|
|
const LONG_TTL = '_REDIS_LONG_TTL_';
|
|
|
|
public function __construct()
|
|
{
|
|
$this->auth = _REDIS_AUTH_STRING_;
|
|
$this->host = _REDIS_HOST_STRING_;
|
|
$this->port = _REDIS_PORT_STRING_;
|
|
$this->db = _REDIS_DB_STRING_;
|
|
$this->default_ttl = _REDIS_DEFAULT_TTL_;
|
|
$this->short_ttl = defined('_REDIS_SHORT_TTL_') ? _REDIS_SHORT_TTL_ : _REDIS_DEFAULT_TTL_;
|
|
$this->medium_ttl = defined('_REDIS_MEDIUM_TTL_') ? _REDIS_MEDIUM_TTL_ : _REDIS_DEFAULT_TTL_;
|
|
$this->long_ttl = defined('_REDIS_LONG_TTL_') ? _REDIS_LONG_TTL_ : _REDIS_DEFAULT_TTL_;
|
|
|
|
if ($this->auth !== '') {
|
|
$this->redis_client = new Predis\Client(['scheme' => 'tcp',
|
|
'host' => $this->host,
|
|
'port' => $this->port,
|
|
'password' => $this->auth,
|
|
],
|
|
['parameters' => [
|
|
'database' => (int)$this->db,
|
|
],
|
|
]);
|
|
} else {
|
|
$this->redis_client = new Predis\Client(['scheme' => 'tcp',
|
|
'host' => $this->host,
|
|
'port' => $this->port,
|
|
],
|
|
['parameters' => [
|
|
'database' => (int)$this->db,
|
|
],
|
|
]);
|
|
}
|
|
try {
|
|
$this->redis_client->connect();
|
|
$this->is_connected = $this->redis_client->isConnected();
|
|
} catch (Exception $e) {
|
|
$this->is_connected = false;
|
|
}
|
|
}
|
|
|
|
public static function getInstance()
|
|
{
|
|
if (!isset(self::$_instance)) {
|
|
self::$_instance = new CacheRedis();
|
|
}
|
|
|
|
return self::$_instance;
|
|
}
|
|
|
|
public function get($key, $controller, $ignoreCheckIp = false)
|
|
{
|
|
if (!$this->isConnected()) {
|
|
return false;
|
|
}
|
|
if (!$ignoreCheckIp && $this->checkIpDisableCache()) {
|
|
return false;
|
|
}
|
|
if ($controller === '') {
|
|
$controller = self::DEFAULT_CONTROLLER_NAME;
|
|
}
|
|
$value = $this->redis_client->get($this->createKey($key, $controller));
|
|
if (null === $value) {
|
|
return false;
|
|
} else {
|
|
return $this->decode($value);
|
|
}
|
|
}
|
|
|
|
public function delete($key)
|
|
{
|
|
if (!$this->isConnected()) {
|
|
return false;
|
|
}
|
|
|
|
return $this->redis_client->del($key);
|
|
}
|
|
|
|
public function del($key) {
|
|
return $this->delete($key);
|
|
}
|
|
|
|
|
|
public function set($key, $controller, $value, $expire = null)
|
|
{
|
|
if (!$this->isConnected()) {
|
|
return false;
|
|
}
|
|
if ($controller === '') {
|
|
$controller = self::DEFAULT_CONTROLLER_NAME;
|
|
}
|
|
if (null === $expire) {
|
|
$expire = (int)$this->default_ttl;
|
|
} else {
|
|
switch ($expire) {
|
|
case self::SHORT_TTL:
|
|
$expire = (int)$this->short_ttl;
|
|
break;
|
|
case self::MEDIUM_TTL:
|
|
$expire = (int)$this->medium_ttl;
|
|
break;
|
|
case self::LONG_TTL:
|
|
$expire = (int)$this->long_ttl;
|
|
break;
|
|
default:
|
|
$expire = (int)$expire;
|
|
break;
|
|
}
|
|
}
|
|
|
|
$this->redis_client->setex($this->createKey($key, $controller), $expire, $this->encode($value));
|
|
}
|
|
|
|
public function expire($key, $controller, $expire)
|
|
{
|
|
if (!$this->isConnected()) {
|
|
return false;
|
|
}
|
|
if ($controller === '') {
|
|
$controller = self::DEFAULT_CONTROLLER_NAME;
|
|
}
|
|
$this->redis_client->expire($this->createKey($key, $controller), $expire);
|
|
}
|
|
|
|
public function isConnected()
|
|
{
|
|
return $this->is_connected;
|
|
}
|
|
|
|
public function flush()
|
|
{
|
|
if (!$this->isConnected()) {
|
|
return false;
|
|
}
|
|
$this->redis_client->flushall();
|
|
}
|
|
|
|
public function setQuery($query, $controller, $value, $expire = null)
|
|
{
|
|
if (!$this->isConnected()) {
|
|
return false;
|
|
}
|
|
if (null === $expire) {
|
|
$expire = (int)$this->default_ttl;
|
|
} else {
|
|
switch ($expire) {
|
|
case self::SHORT_TTL:
|
|
$expire = (int)$this->short_ttl;
|
|
break;
|
|
case self::MEDIUM_TTL:
|
|
$expire = (int)$this->medium_ttl;
|
|
break;
|
|
case self::LONG_TTL:
|
|
$expire = (int)$this->long_ttl;
|
|
break;
|
|
default:
|
|
$expire = (int)$expire;
|
|
break;
|
|
}
|
|
}
|
|
if ($controller === '') {
|
|
$controller = self::DEFAULT_CONTROLLER_NAME;
|
|
}
|
|
if (is_string($query) && trim($query) !== '') {
|
|
$this->redis_client->setex($this->createKey($query, $controller), $expire, $this->encode($value));
|
|
}
|
|
}
|
|
|
|
public function getQuery($query, $controller, $ignoreCheckIp = false)
|
|
{
|
|
if (!$this->isConnected()) {
|
|
return false;
|
|
}
|
|
if (!$ignoreCheckIp && $this->checkIpDisableCache()) {
|
|
return false;
|
|
}
|
|
if ($controller === '') {
|
|
$controller = self::DEFAULT_CONTROLLER_NAME;
|
|
}
|
|
$value = null;
|
|
if (is_string($query) && trim($query) !== '') {
|
|
$value = $this->redis_client->get($this->createKey($query, $controller));
|
|
}
|
|
if (is_null($value)) {
|
|
return false;
|
|
} else {
|
|
return $this->decode($value);
|
|
}
|
|
}
|
|
|
|
public function scan($key, $count = 1024)
|
|
{
|
|
$result = array();
|
|
|
|
foreach (new Iterator\Keyspace(
|
|
$this->redis_client,
|
|
$key,
|
|
$count
|
|
) as $result_key) {
|
|
$result[] = $result_key;
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
|
|
public function clear($key)
|
|
{
|
|
|
|
$keys = $this->scan($key);
|
|
$replies = false;
|
|
foreach (array_chunk($keys, 256) as $data) {
|
|
$pipe = $this->redis_client->pipeline();
|
|
foreach ($data as $item) {
|
|
$pipe->del($item);
|
|
}
|
|
$replies = $pipe->execute();
|
|
}
|
|
|
|
return $replies;
|
|
}
|
|
|
|
private function encode($value)
|
|
{
|
|
return serialize($value);
|
|
}
|
|
|
|
private function decode($value)
|
|
{
|
|
return unserialize($value);
|
|
}
|
|
|
|
private function createKey($key, $controller)
|
|
{
|
|
return $controller . '-' . hash(self::HASHING_ALGORITHM, $key);
|
|
}
|
|
|
|
private function checkIpDisableCache()
|
|
{
|
|
$disableCache = false;
|
|
$no_cache_ip = Configuration::get('PS_REDIS_NOCACHE_IP');
|
|
if ($no_cache_ip) {
|
|
$no_cache_ip_list = explode(',', $no_cache_ip);
|
|
if (isset($_SERVER['REMOTE_ADDR']) && in_array($_SERVER['REMOTE_ADDR'], $no_cache_ip_list)) {
|
|
$disableCache = true;
|
|
}
|
|
}
|
|
|
|
return $disableCache;
|
|
}
|
|
}
|