Skip to content
This repository has been archived by the owner on Nov 15, 2020. It is now read-only.

Commit

Permalink
Merge pull request #55 from elricho/master
Browse files Browse the repository at this point in the history
Add Redis as caching option.
  • Loading branch information
elricho authored Feb 21, 2017
2 parents 65aa18e + 626f6b9 commit 18cb401
Show file tree
Hide file tree
Showing 5 changed files with 202 additions and 1 deletion.
2 changes: 2 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ php:

services:
- memcached
- redis-server

notifications:
slack:
Expand All @@ -23,6 +24,7 @@ before_install:
- if [[ $TRAVIS_PHP_VERSION != 'hhvm' ]]; then phpenv config-add ./tests/travis_php.ini; fi;
- travis_retry composer self-update
- travis_retry composer install --no-interaction --prefer-source
- travis_retry composer require predis/predis:^1.1

# Setup test run config files
before_script:
Expand Down
17 changes: 16 additions & 1 deletion readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ Note : Increase the default timeout before downloading the archive.

## Flexible Caching Options

Version 4.1.* includes APC(u), Memcache and Memcached caching options. For backwards compatibility if no option
Version 4.1.* includes APC(u), Memcache, Memcached and Redis caching options. For backwards compatibility if no option
is set in the config file then it defaults to APC.

### Using Memcache
Expand Down Expand Up @@ -172,6 +172,21 @@ If you're using cache connection pooling then pass the pool name as follows :
)
);

### Using Redis

From version 4.1.11 we also have Redis as a caching option. Redis caching use
Predis, which you should include via composer. Use a caching config as follows:


$hdconfig['cache'] = array (
'redis' => array (
'scheme' => 'tcp',
'host' => '127.0.0.1',
'port' => 6379
)
);


## Extra Examples ##

Additional examples can be found in the examples.php file.
Expand Down
86 changes: 86 additions & 0 deletions src/Cache/Redis.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
<?php
/*
** Copyright (c) Richard Uren 2017 - 2017 <[email protected]>
** All Rights Reserved
**
** --
**
** LICENSE: Redistribution and use in source and binary forms, with or
** without modification, are permitted provided that the following
** conditions are met: Redistributions of source code must retain the
** above copyright notice, this list of conditions and the following
** disclaimer. Redistributions in binary form must reproduce the above
** copyright notice, this list of conditions and the following disclaimer
** in the documentation and/or other materials provided with the
** distribution.
**
** THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
** WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
** MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
** NO EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
** OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
** TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
** USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

namespace HandsetDetection\Cache;

use HandsetDetection\Cache\CacheInterface;

class Redis implements CacheInterface {

protected $redis;
private $name = 'redis';

public function __construct($config=array()) {
if (! class_exists("\Predis\Client")) {
throw new \RuntimeException('Redis functions not available. Is the Predis module installed ?');
}

$options = @$config['cache']['redis'];

// Create handle
$this->redis = empty($options) ? new \Predis\Client() : new \Predis\Client($options);
}

/** Get key */
public function get($key) {
$data = $this->redis->get($key);
if ($data === false)
return null;
if (empty($data))
return null;
return unserialize($data);
}

/** Set key */
public function set($key, $data, $ttl) {
$code = $this->redis->set($key, serialize($data));
if (! $code)
return null;
if ($ttl) {
return ($this->redis->expire($key, $ttl) == 1) ? true : null;
}
return true;
}

/** Delete key */
public function del($key) {
return ($this->redis->del($key) == 1) ? true : null;
}

/** Flush Cache */
public function flush() {
if (! $this->redis->flushdb())
return null;
return true;
}

/** Return cache name **/
public function getName() {
return $this->name;
}
}
3 changes: 3 additions & 0 deletions src/HDCache.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
use HandsetDetection\Cache\Memcached;
use HandsetDetection\Cache\File;
use HandsetDetection\Cache\None;
use HandsetDetection\Cache\Redis;

class HDCache {
var $prefix;
Expand Down Expand Up @@ -79,6 +80,8 @@ function setConfig($config) {
$this->cache = new APC($config);
elseif (isset($config['cache']['apcu']))
$this->cache = new APCu($config);
elseif (isset($config['cache']['redis']))
$this->cache = new Redis($config);
elseif (! isset($config['cache'])) {
// The legacy option was to use apc/apc by default - so use apcu/apc if 'cache' is not set
if (function_exists('apcu_store'))
Expand Down
95 changes: 95 additions & 0 deletions tests/Cache/RedisTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
<?php

class RedisTest extends PHPUnit_Framework_TestCase {
var $volumeTest = 10000;
var $testData = array(
'roses' => 'red',
'fish' => 'blue',
'sugar' => 'sweet',
'number' => 4
);

function setup() {
if (! class_exists('\Predis\Client')) {
$this->markTestSkipped('Predis class not available. Please install via composer.');
}
}

function testBasic() {
$config = array(
'cache' => array(
'redis' => array(
'scheme' => 'tcp',
'host' => '127.0.0.1',
'port' => 6379
)
)
);

$cache = new HandsetDetection\HDCache($config);
$now = time();

// Test Write & Read
$cache->write($now, $this->testData);
$reply = $cache->read($now);
$this->assertEquals($this->testData, $reply);

// Test Flush
$reply = $cache->purge();
$this->assertTrue($reply);
$reply = $cache->read($now);
$this->assertNull($reply);
}

function testVolume() {
$config = array(
'cache' => array(
'redis' => array(
'scheme' => 'tcp',
'host' => '127.0.0.1',
'port' => 6379
)
)
);

$cache = new HandsetDetection\HDCache($config);
$now = time();

for($i=0; $i < $this->volumeTest; $i++) {
$key = 'test'.$now.$i;

// Write
$reply = $cache->write($key, $this->testData);
$this->assertTrue($reply);

// Read
$reply = $cache->read($key);
$this->assertEquals($this->testData, $reply);

// Delete
$reply = $cache->delete($key);
$this->assertTrue($reply);

// Read
$reply = $cache->read($key);
$this->assertNull($reply);
}
$end = time();
$cache->purge();
}

function testGetName() {
$config = array(
'cache' => array(
'redis' => array(
'scheme' => 'tcp',
'host' => '127.0.0.1',
'port' => 6379
)
)
);

$cache = new HandsetDetection\HDCache($config);
$this->assertEquals('redis', $cache->getName());
}
}

0 comments on commit 18cb401

Please sign in to comment.