diff --git a/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/RedisSessionHandler.php b/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/RedisSessionHandler.php new file mode 100644 index 0000000000000..61de56dbba0b9 --- /dev/null +++ b/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/RedisSessionHandler.php @@ -0,0 +1,119 @@ + + * + * 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 + */ +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; + } +} diff --git a/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/RedisSessionHandlerTest.php b/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/RedisSessionHandlerTest.php new file mode 100644 index 0000000000000..00cb64228c8ea --- /dev/null +++ b/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/RedisSessionHandlerTest.php @@ -0,0 +1,134 @@ + + * + * 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)); + } +} pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy