8000 Added Redis session storage by masterklavi · Pull Request #18233 · symfony/symfony · GitHub
[go: up one dir, main page]

Skip to content

Added Redis session storage #18233

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Symfony\Component\HttpFoundation\Session\Storage\Handler;

/**
* RedisSessionHandler.
*
* @author Master Klavi <masterklavi@gmail.com>
*/
class RedisSessionHandler implements \SessionHandlerInterface
{
/**
* @var \Redis Redis driver.
*/
private $redis;

/**
* @var int Time to live in seconds
*/
private $ttl;

/**
* @var string Key prefix for shared environments.
*/
private $prefix;

/**
* Constructor.
*
* List of available options:
* * prefix: The prefix to use for the redis keys in order to avoid collision
* * expiretime: The time to live in seconds
*
* @param \Redis $redis A \Redis instance
* @param array $options An associative array options
*
* @throws \InvalidArgumentException When unsupported options are passed
*/
public function __construct(\Redis $redis, array $options = array())
{
if ($diff = array_diff(array_keys($options), array('prefix', 'expiretime'))) {
throw new \InvalidArgumentException(sprintf(
'The following options are not supported "%s"', implode(', ', $diff)
));
}

$this->redis = $redis;
$this->ttl = isset($options['expiretime']) ? (int) $options['expiretime'] : 86400;
$this->prefix = isset($options['prefix']) ? $options['prefix'] : 'sf2s';
}

/**
* {@inheritdoc}
*/
public function open($savePath, $sessionName)
{
return true;
}

/**
* {@inheritdoc}
*/
public function close()
{
return $this->redis->close();
}

/**
* {@inheritdoc}
*/
public function read($sessionId)
{
return $this->redis->get($this->prefix.$sessionId) ?: '';
}

/**
* {@inheritdoc}
*/
public function write($sessionId, $data)
{
return $this->redis->setEx($this->prefix.$sessionId, $this->ttl, $data);
}

/**
* {@inheritdoc}
*/
public function destroy($sessionId)
{
return $this->redis->delete($this->prefix.$sessionId);
}

/**
* {@inheritdoc}
*/
public function gc($maxlifetime)
{
// not required here because redis will auto expire the records anyhow.
return true;
}

/**
* Return a Redis instance.
*
* @return \Redis
*/
protected function getRedis()
{
return $this->redis;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Symfony\Component\HttpFoundation\Tests\Session\Storage\Handler;

use Symfony\Component\HttpFoundation\Session\Storage\Handler\RedisSessionHandler;

/**
* @requires extension redis
* @group time-sensitive
*/
class RedisSessionHandlerTest extends \PHPUnit_Framework_TestCase
{
const PREFIX = 'prefix_';
const TTL = 1000;
/**
* @var RedisSessionHandler
*/
protected $storage;

protected $redis;

protected function setUp()
{
parent::setUp();
$this->redis = $this->getMock('Redis');
$this->storage = new RedisSessionHandler(
$this->redis,
array('prefix' => self::PREFIX, 'expiretime' => self::TTL)
);
}

protected function tearDown()
{
$this->redis = null;
$this->storage = null;
parent::tearDown();
}

public function testOpenSession()
{
$this->assertTrue($this->storage->open('', ''));
}

public function testCloseSession()
{
$this->redis
->expects($this->once())
->method('close')
->will($this->returnValue(true))
;

$this->assertTrue($this->storage->close());
}

public function testReadSession()
{
$this->redis
->expects($this->once())
->method('get')
->with(self::PREFIX.'id')
;

$this->assertEquals('', $this->storage->read('id'));
}

public function testWriteSession()
{
$this->redis
->expects($this->once())
->method('setEx')
->with(self::PREFIX.'id', $this->equalTo(self::TTL, 2), 'data')
->will($this->returnValue(true))
;

$this->assertTrue($this->storage->write('id', 'data'));
}

public function testDestroySession()
{
$this->redis
->expects($this->once())
->method('delete')
->with(self::PREFIX.'id')
->will($this->returnValue(true))
;

$this->assertTrue($this->storage->destroy('id'));
}

public function testGcSession()
{
$this->assertTrue($this->storage->gc(123));
}

/**
* @dataProvider getOptionFixtures
*/
public function testSupportedOptions($options, $supported)
{
try {
new RedisSessionHandler($this->redis, $options);
$this->assertTrue($supported);
} catch (\InvalidArgumentException $e) {
$this->assertFalse($supported);
}
}

public function getOptionFixtures()
{
return array(
array(array('prefix' => 'session'), true),
array(array('expiretime' => 100), true),
array(array('prefix' => 'session', 'expiretime' => 200), true),
array(array('expiretime' => 100, 'foo' => 'bar'), false),
);
}

public function testGetConnection()
{
$method = new \ReflectionMethod($this->storage, 'getRedis');
$method->setAccessible(true);

$this->assertInstanceOf('\Redis', $method->invoke($this->storage));
}
}
0