diff --git a/src/Core/Cache.php b/src/Core/Cache.php index f1d1e11a54..4202db325c 100644 --- a/src/Core/Cache.php +++ b/src/Core/Cache.php @@ -40,6 +40,12 @@ class Cache extends \Friendica\BaseObject self::$driver = new Cache\MemcachedCacheDriver($memcached_hosts); break; + case 'redis': + $redis_host = Config::get('system', 'redis_host', '127.0.0.1'); + $redis_port = Config::get('system', 'redis_port', 6379); + + self::$driver = new Cache\RedisCacheDriver($redis_host, $redis_port); + break; default: self::$driver = new Cache\DatabaseCacheDriver(); } diff --git a/src/Core/Cache/RedisCacheDriver.php b/src/Core/Cache/RedisCacheDriver.php new file mode 100644 index 0000000000..fa98842da0 --- /dev/null +++ b/src/Core/Cache/RedisCacheDriver.php @@ -0,0 +1,77 @@ + + * @author Roland Haeder + */ +class RedisCacheDriver extends BaseObject implements ICacheDriver +{ + /** + * @var Redis + */ + private $redis; + + public function __construct($redis_host, $redis_port) + { + if (!class_exists('Redis', false)) { + throw new \Exception('Redis class isn\'t available'); + } + + $this->redis = new \Redis(); + + if (!$this->redis->connect($redis_host, $redis_port)) { + throw new \Exception('Expected Redis server at ' . $redis_host . ':' . $redis_port . ' isn\'t available'); + } + } + + public function get($key) + { + $return = null; + + // We fetch with the hostname as key to avoid problems with other applications + $cached = $this->redis->get(self::getApp()->get_hostname() . ':' . $key); + + // @see http://php.net/manual/en/redis.get.php#84275 + if (is_bool($cached) || is_double($cached) || is_long($cached)) { + return $return; + } + + $value = @unserialize($cached); + + // Only return a value if the serialized value is valid. + // We also check if the db entry is a serialized + // boolean 'false' value (which we want to return). + if ($cached === serialize(false) || $value !== false) { + $return = $value; + } + + return $return; + } + + public function set($key, $value, $duration = Cache::MONTH) + { + // We store with the hostname as key to avoid problems with other applications + return $this->redis->set( + self::getApp()->get_hostname() . ":" . $key, + serialize($value), + time() + $duration + ); + } + + public function delete($key) + { + return $this->redis->delete($key); + } + + public function clear() + { + return true; + } +}