[2.3] Handle PHP sessions started outside of Symfony

This commit is contained in:
Drak 2013-04-05 12:57:01 +01:00 committed by Fabien Potencier
parent a7c9863b3a
commit df99902a01
9 changed files with 465 additions and 33 deletions

View File

@ -318,6 +318,7 @@ class FrameworkExtension extends Extension
if (null == $config['handler_id']) { if (null == $config['handler_id']) {
// Set the handler class to be null // Set the handler class to be null
$container->getDefinition('session.storage.native')->replaceArgument(1, null); $container->getDefinition('session.storage.native')->replaceArgument(1, null);
$container->getDefinition('session.storage.php_bridge')->replaceArgument(1, null);
} else { } else {
$container->setAlias('session.handler', $config['handler_id']); $container->setAlias('session.handler', $config['handler_id']);
} }
@ -327,6 +328,7 @@ class FrameworkExtension extends Extension
$this->addClassesToCompile(array( $this->addClassesToCompile(array(
'Symfony\\Bundle\\FrameworkBundle\\EventListener\\SessionListener', 'Symfony\\Bundle\\FrameworkBundle\\EventListener\\SessionListener',
'Symfony\\Component\\HttpFoundation\\Session\\Storage\\NativeSessionStorage', 'Symfony\\Component\\HttpFoundation\\Session\\Storage\\NativeSessionStorage',
'Symfony\\Component\\HttpFoundation\\Session\\Storage\\PhpBridgeSessionStorage',
'Symfony\\Component\\HttpFoundation\\Session\\Storage\\Handler\\NativeFileSessionHandler', 'Symfony\\Component\\HttpFoundation\\Session\\Storage\\Handler\\NativeFileSessionHandler',
'Symfony\\Component\\HttpFoundation\\Session\\Storage\\Proxy\\AbstractProxy', 'Symfony\\Component\\HttpFoundation\\Session\\Storage\\Proxy\\AbstractProxy',
'Symfony\\Component\\HttpFoundation\\Session\\Storage\\Proxy\\SessionHandlerProxy', 'Symfony\\Component\\HttpFoundation\\Session\\Storage\\Proxy\\SessionHandlerProxy',

View File

@ -9,6 +9,7 @@
<parameter key="session.flashbag.class">Symfony\Component\HttpFoundation\Session\Flash\FlashBag</parameter> <parameter key="session.flashbag.class">Symfony\Component\HttpFoundation\Session\Flash\FlashBag</parameter>
<parameter key="session.attribute_bag.class">Symfony\Component\HttpFoundation\Session\Attribute\AttributeBag</parameter> <parameter key="session.attribute_bag.class">Symfony\Component\HttpFoundation\Session\Attribute\AttributeBag</parameter>
<parameter key="session.storage.native.class">Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorage</parameter> <parameter key="session.storage.native.class">Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorage</parameter>
<parameter key="session.storage.php_bridge.class">Symfony\Component\HttpFoundation\Session\Storage\PhpBridgeSessionStorage</parameter>
<parameter key="session.storage.mock_file.class">Symfony\Component\HttpFoundation\Session\Storage\MockFileSessionStorage</parameter> <parameter key="session.storage.mock_file.class">Symfony\Component\HttpFoundation\Session\Storage\MockFileSessionStorage</parameter>
<parameter key="session.handler.native_file.class">Symfony\Component\HttpFoundation\Session\Storage\Handler\NativeFileSessionHandler</parameter> <parameter key="session.handler.native_file.class">Symfony\Component\HttpFoundation\Session\Storage\Handler\NativeFileSessionHandler</parameter>
<parameter key="session_listener.class">Symfony\Bundle\FrameworkBundle\EventListener\SessionListener</parameter> <parameter key="session_listener.class">Symfony\Bundle\FrameworkBundle\EventListener\SessionListener</parameter>
@ -26,6 +27,10 @@
<argument type="service" id="session.handler" /> <argument type="service" id="session.handler" />
</service> </service>
<service id="session.storage.php_bridge" class="%session.storage.php_bridge.class%">
<argument type="service" id="session.handler" />
</service>
<service id="session.flash_bag" class="%session.flashbag.class%" public="false" /> <service id="session.flash_bag" class="%session.flashbag.class%" public="false" />
<service id="session.attribute_bag" class="%session.attribute_bag.class%" public="false" /> <service id="session.attribute_bag" class="%session.attribute_bag.class%" public="false" />

View File

@ -12,6 +12,7 @@
namespace Symfony\Component\HttpFoundation\Session\Storage; namespace Symfony\Component\HttpFoundation\Session\Storage;
use Symfony\Component\HttpFoundation\Session\SessionBagInterface; use Symfony\Component\HttpFoundation\Session\SessionBagInterface;
use Symfony\Component\HttpFoundation\Session\Storage\Handler\NativeSessionHandler;
use Symfony\Component\HttpFoundation\Session\Storage\MetadataBag; use Symfony\Component\HttpFoundation\Session\Storage\MetadataBag;
use Symfony\Component\HttpFoundation\Session\Storage\Proxy\NativeProxy; use Symfony\Component\HttpFoundation\Session\Storage\Proxy\NativeProxy;
use Symfony\Component\HttpFoundation\Session\Storage\Proxy\AbstractProxy; use Symfony\Component\HttpFoundation\Session\Storage\Proxy\AbstractProxy;
@ -91,9 +92,9 @@ class NativeSessionStorage implements SessionStorageInterface
* upload_progress.min-freq, "1" * upload_progress.min-freq, "1"
* url_rewriter.tags, "a=href,area=href,frame=src,form=,fieldset=" * url_rewriter.tags, "a=href,area=href,frame=src,form=,fieldset="
* *
* @param array $options Session configuration options. * @param array $options Session configuration options.
* @param object $handler SessionHandlerInterface. * @param AbstractProxy|NativeSessionHandler|\SessionHandlerInterface|null $handler
* @param MetadataBag $metaBag MetadataBag. * @param MetadataBag $metaBag MetadataBag.
*/ */
public function __construct(array $options = array(), $handler = null, MetadataBag $metaBag = null) public function __construct(array $options = array(), $handler = null, MetadataBag $metaBag = null)
{ {
@ -130,27 +131,28 @@ class NativeSessionStorage implements SessionStorageInterface
return true; return true;
} }
// catch condition where session was started automatically by PHP if (version_compare(phpversion(), '5.4.0', '>=') && \PHP_SESSION_ACTIVE === session_status()) {
if (!$this->started && !$this->closed && $this->saveHandler->isActive() throw new \RuntimeException('Failed to start the session: already started by PHP.');
&& $this->saveHandler->isSessionHandlerInterface()) { }
$this->loadSession();
return true; if (version_compare(phpversion(), '5.4.0', '<') && isset($_SESSION) && session_id()) {
// not 100% fool-proof, but is the most reliable way to determine if a session is active in PHP 5.3
throw new \RuntimeException('Failed to start the session: already started by PHP ($_SESSION is set).');
} }
if (ini_get('session.use_cookies') && headers_sent()) { if (ini_get('session.use_cookies') && headers_sent()) {
throw new \RuntimeException('Failed to start the session because headers have already been sent.'); throw new \RuntimeException('Failed to start the session because headers have already been sent.');
} }
// start the session // ok to try and start the session
if (!session_start()) { if (!session_start()) {
throw new \RuntimeException('Failed to start the session'); throw new \RuntimeException('Failed to start the session');
} }
$this->loadSession(); $this->loadSession();
if (!$this->saveHandler->isWrapper() && !$this->saveHandler->isSessionHandlerInterface()) { if (!$this->saveHandler->isWrapper() && !$this->saveHandler->isSessionHandlerInterface()) {
$this->saveHandler->setActive(false); // This condition matches only PHP 5.3 with internal save handlers
$this->saveHandler->setActive(true);
} }
return true; return true;
@ -215,7 +217,8 @@ class NativeSessionStorage implements SessionStorageInterface
{ {
session_write_close(); session_write_close();
if (!$this->saveHandler->isWrapper() && !$this->getSaveHandler()->isSessionHandlerInterface()) { if (!$this->saveHandler->isWrapper() && !$this->saveHandler->isSessionHandlerInterface()) {
// This condition matches only PHP 5.3 with internal save handlers
$this->saveHandler->setActive(false); $this->saveHandler->setActive(false);
} }
@ -329,7 +332,7 @@ class NativeSessionStorage implements SessionStorageInterface
} }
/** /**
* Registers save handler as a PHP session handler. * Registers session save handler as a PHP session handler.
* *
* To use internal PHP session save handlers, override this method using ini_set with * To use internal PHP session save handlers, override this method using ini_set with
* session.save_handler and session.save_path e.g. * session.save_handler and session.save_path e.g.
@ -337,21 +340,35 @@ class NativeSessionStorage implements SessionStorageInterface
* ini_set('session.save_handler', 'files'); * ini_set('session.save_handler', 'files');
* ini_set('session.save_path', /tmp'); * ini_set('session.save_path', /tmp');
* *
* or pass in a NativeSessionHandler instance which configures session.save_handler in the
* constructor, for a template see NativeFileSessionHandler or use handlers in
* composer package drak/native-session
*
* @see http://php.net/session-set-save-handler * @see http://php.net/session-set-save-handler
* @see http://php.net/sessionhandlerinterface * @see http://php.net/sessionhandlerinterface
* @see http://php.net/sessionhandler * @see http://php.net/sessionhandler
* @see http://github.com/drak/NativeSession
* *
* @param object $saveHandler Default null means NativeProxy. * @param AbstractProxy|NativeSessionHandler|\SessionHandlerInterface|null $saveHandler
*
* @throws \InvalidArgumentException
*/ */
public function setSaveHandler($saveHandler = null) public function setSaveHandler($saveHandler = null)
{ {
// Wrap $saveHandler in proxy if (!$saveHandler instanceof AbstractProxy &&
!$saveHandler instanceof NativeSessionHandler &&
!$saveHandler instanceof \SessionHandlerInterface &&
null !== $saveHandler) {
throw new \InvalidArgumentException('Must be instance of AbstractProxy or NativeSessionHandler; implement \SessionHandlerInterface; or be null.');
}
// Wrap $saveHandler in proxy and prevent double wrapping of proxy
if (!$saveHandler instanceof AbstractProxy && $saveHandler instanceof \SessionHandlerInterface) { if (!$saveHandler instanceof AbstractProxy && $saveHandler instanceof \SessionHandlerInterface) {
$saveHandler = new SessionHandlerProxy($saveHandler); $saveHandler = new SessionHandlerProxy($saveHandler);
} elseif (!$saveHandler instanceof AbstractProxy) { } elseif (!$saveHandler instanceof AbstractProxy) {
$saveHandler = new NativeProxy(); $saveHandler = version_compare(phpversion(), '5.4.0', '>=') ?
new SessionHandlerProxy(new \SessionHandler()) : new NativeProxy();
} }
$this->saveHandler = $saveHandler; $this->saveHandler = $saveHandler;
if ($this->saveHandler instanceof \SessionHandlerInterface) { if ($this->saveHandler instanceof \SessionHandlerInterface) {

View File

@ -0,0 +1,69 @@
<?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;
use Symfony\Component\HttpFoundation\Session\Storage\MetadataBag;
use Symfony\Component\HttpFoundation\Session\Storage\Proxy\AbstractProxy;
use Symfony\Component\HttpFoundation\Session\Storage\Handler\NativeSessionHandler;
/**
* Allows session to be started by PHP and managed by Symfony2
*
* @author Drak <drak@zikula.org>
*/
class PhpBridgeSessionStorage extends NativeSessionStorage
{
/**
* Constructor.
*
* @param AbstractProxy|NativeSessionHandler|\SessionHandlerInterface|null $handler
* @param MetadataBag $metaBag MetadataBag
*/
public function __construct($handler = null, MetadataBag $metaBag = null)
{
$this->setMetadataBag($metaBag);
$this->setSaveHandler($handler);
}
/**
* {@inheritdoc}
*/
public function start()
{
if ($this->started && !$this->closed) {
return true;
}
$this->loadSession();
if (!$this->saveHandler->isWrapper() && !$this->saveHandler->isSessionHandlerInterface()) {
// This condition matches only PHP 5.3 + internal save handlers
$this->saveHandler->setActive(true);
}
return true;
}
/**
* {@inheritdoc}
*/
public function clear()
{
// clear out the bags and nothing else that may be set
// since the purpose of this driver is to share a handler
foreach ($this->bags as $bag) {
$bag->clear();
}
// reconnect the bags to the session
$this->loadSession();
}
}

View File

@ -72,16 +72,31 @@ abstract class AbstractProxy
*/ */
public function isActive() public function isActive()
{ {
if (version_compare(phpversion(), '5.4.0', '>=')) {
return $this->active = \PHP_SESSION_ACTIVE === session_status();
}
return $this->active; return $this->active;
} }
/** /**
* Sets the active flag. * Sets the active flag.
* *
* Has no effect under PHP 5.4+ as status is detected
* automatically in isActive()
*
* @internal
*
* @param Boolean $flag * @param Boolean $flag
*
* @throws \LogicException
*/ */
public function setActive($flag) public function setActive($flag)
{ {
if (version_compare(phpversion(), '5.4.0', '>=')) {
throw new \LogicException('This method is disabled in PHP 5.4.0+');
}
$this->active = (bool) $flag; $this->active = (bool) $flag;
} }

View File

@ -11,11 +11,15 @@
namespace Symfony\Component\HttpFoundation\Tests\Session\Storage; namespace Symfony\Component\HttpFoundation\Tests\Session\Storage;
use Symfony\Component\HttpFoundation\Session\Storage\Handler\NativeSessionHandler;
use Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorage; use Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorage;
use Symfony\Component\HttpFoundation\Session\Storage\Handler\NativeFileSessionHandler; use Symfony\Component\HttpFoundation\Session\Storage\Handler\NativeFileSessionHandler;
use Symfony\Component\HttpFoundation\Session\Storage\Handler\NullSessionHandler; use Symfony\Component\HttpFoundation\Session\Storage\Handler\NullSessionHandler;
use Symfony\Component\HttpFoundation\Session\Flash\FlashBag; use Symfony\Component\HttpFoundation\Session\Flash\FlashBag;
use Symfony\Component\HttpFoundation\Session\Attribute\AttributeBag; use Symfony\Component\HttpFoundation\Session\Attribute\AttributeBag;
use Symfony\Component\HttpFoundation\Session\Storage\Proxy\AbstractProxy;
use Symfony\Component\HttpFoundation\Session\Storage\Proxy\NativeProxy;
use Symfony\Component\HttpFoundation\Session\Storage\Proxy\SessionHandlerProxy;
/** /**
* Test class for NativeSessionStorage. * Test class for NativeSessionStorage.
@ -28,6 +32,28 @@ use Symfony\Component\HttpFoundation\Session\Attribute\AttributeBag;
*/ */
class NativeSessionStorageTest extends \PHPUnit_Framework_TestCase class NativeSessionStorageTest extends \PHPUnit_Framework_TestCase
{ {
private $savePath;
protected function setUp()
{
ini_set('session.save_handler', 'files');
ini_set('session.save_path', $this->savePath = sys_get_temp_dir().'/sf2test');
if (!is_dir($this->savePath)) {
mkdir($this->savePath);
}
}
protected function tearDown()
{
session_write_close();
array_map('unlink', glob($this->savePath.'/*'));
if (is_dir($this->savePath)) {
rmdir($this->savePath);
}
$this->savePath = null;
}
/** /**
* @param array $options * @param array $options
* *
@ -75,7 +101,6 @@ class NativeSessionStorageTest extends \PHPUnit_Framework_TestCase
$storage->regenerate(); $storage->regenerate();
$this->assertNotEquals($id, $storage->getId()); $this->assertNotEquals($id, $storage->getId());
$this->assertEquals(7, $storage->getBag('attributes')->get('lucky')); $this->assertEquals(7, $storage->getBag('attributes')->get('lucky'));
} }
public function testRegenerateDestroy() public function testRegenerateDestroy()
@ -126,32 +151,132 @@ class NativeSessionStorageTest extends \PHPUnit_Framework_TestCase
$this->assertEquals($options, $gco); $this->assertEquals($options, $gco);
} }
public function testSetSaveHandler() /**
* @expectedException \InvalidArgumentException
*/
public function testSetSaveHandlerException()
{ {
$storage = $this->getStorage(); $storage = $this->getStorage();
$storage->setSaveHandler(new \StdClass()); $storage->setSaveHandler(new \StdClass);
}
public function testSetSaveHandler53()
{
if (version_compare(phpversion(), '5.4.0', '>=')) {
$this->markTestSkipped('Test skipped, for PHP 5.3 only.');
}
ini_set('session.save_handler', 'files');
$storage = $this->getStorage();
$storage->setSaveHandler();
$this->assertInstanceOf('Symfony\Component\HttpFoundation\Session\Storage\Proxy\NativeProxy', $storage->getSaveHandler());
$storage->setSaveHandler(null);
$this->assertInstanceOf('Symfony\Component\HttpFoundation\Session\Storage\Proxy\NativeProxy', $storage->getSaveHandler());
$storage->setSaveHandler(new NativeSessionHandler());
$this->assertInstanceOf('Symfony\Component\HttpFoundation\Session\Storage\Proxy\NativeProxy', $storage->getSaveHandler());
$storage->setSaveHandler(new SessionHandlerProxy(new SessionHandler()));
$this->assertInstanceOf('Symfony\Component\HttpFoundation\Session\Storage\Proxy\SessionHandlerProxy', $storage->getSaveHandler());
$storage->setSaveHandler(new SessionHandler());
$this->assertInstanceOf('Symfony\Component\HttpFoundation\Session\Storage\Proxy\SessionHandlerProxy', $storage->getSaveHandler());
$storage->setSaveHandler(new NativeProxy());
$this->assertInstanceOf('Symfony\Component\HttpFoundation\Session\Storage\Proxy\NativeProxy', $storage->getSaveHandler()); $this->assertInstanceOf('Symfony\Component\HttpFoundation\Session\Storage\Proxy\NativeProxy', $storage->getSaveHandler());
} }
public function testSetSaveHandlerPHP53() public function testSetSaveHandler54()
{
if (version_compare(phpversion(), '5.4.0', '<')) {
$this->markTestSkipped('Test skipped, for PHP 5.4 only.');
}
ini_set('session.save_handler', 'files');
$storage = $this->getStorage();
$storage->setSaveHandler();
$this->assertInstanceOf('Symfony\Component\HttpFoundation\Session\Storage\Proxy\SessionHandlerProxy', $storage->getSaveHandler());
$storage->setSaveHandler(null);
$this->assertInstanceOf('Symfony\Component\HttpFoundation\Session\Storage\Proxy\SessionHandlerProxy', $storage->getSaveHandler());
$storage->setSaveHandler(new SessionHandlerProxy(new NativeSessionHandler()));
$this->assertInstanceOf('Symfony\Component\HttpFoundation\Session\Storage\Proxy\SessionHandlerProxy', $storage->getSaveHandler());
$storage->setSaveHandler(new NativeSessionHandler());
$this->assertInstanceOf('Symfony\Component\HttpFoundation\Session\Storage\Proxy\SessionHandlerProxy', $storage->getSaveHandler());
$storage->setSaveHandler(new SessionHandlerProxy(new SessionHandler()));
$this->assertInstanceOf('Symfony\Component\HttpFoundation\Session\Storage\Proxy\SessionHandlerProxy', $storage->getSaveHandler());
$storage->setSaveHandler(new SessionHandler());
$this->assertInstanceOf('Symfony\Component\HttpFoundation\Session\Storage\Proxy\SessionHandlerProxy', $storage->getSaveHandler());
}
/**
* @expectedException \RuntimeException
*/
public function testStartedOutside53()
{ {
if (version_compare(phpversion(), '5.4.0', '>=')) { if (version_compare(phpversion(), '5.4.0', '>=')) {
$this->markTestSkipped('Test skipped, for PHP 5.3 only.'); $this->markTestSkipped('Test skipped, for PHP 5.3 only.');
} }
$storage = $this->getStorage(); $storage = $this->getStorage();
$storage->setSaveHandler(new NativeFileSessionHandler());
$this->assertInstanceOf('Symfony\Component\HttpFoundation\Session\Storage\Proxy\NativeProxy', $storage->getSaveHandler()); $this->assertFalse(isset($_SESSION));
session_start();
$this->assertTrue(isset($_SESSION));
// PHP session might have started, but the storage driver has not, so false is correct here
$this->assertFalse($storage->isStarted());
$key = $storage->getMetadataBag()->getStorageKey();
$this->assertFalse(isset($_SESSION[$key]));
$storage->start();
} }
public function testSetSaveHandlerPHP54() /**
* @expectedException \RuntimeException
*/
public function testCanStartOutside54()
{ {
if (version_compare(phpversion(), '5.4.0', '<')) { if (version_compare(phpversion(), '5.4.0', '<')) {
$this->markTestSkipped('Test skipped, for PHP 5.4+ only.'); $this->markTestSkipped('Test skipped, for PHP 5.4 only.');
} }
$storage = $this->getStorage(); $storage = $this->getStorage();
$storage->setSaveHandler(new NullSessionHandler());
$this->assertInstanceOf('Symfony\Component\HttpFoundation\Session\Storage\Proxy\SessionHandlerProxy', $storage->getSaveHandler()); $this->assertFalse(isset($_SESSION));
$this->assertFalse($storage->getSaveHandler()->isActive());
$this->assertFalse($storage->isStarted());
session_start();
$this->assertTrue(isset($_SESSION));
$this->assertTrue($storage->getSaveHandler()->isActive());
// PHP session might have started, but the storage driver has not, so false is correct here
$this->assertFalse($storage->isStarted());
$key = $storage->getMetadataBag()->getStorageKey();
$this->assertFalse(isset($_SESSION[$key]));
$storage->start();
}
}
class SessionHandler implements \SessionHandlerInterface
{
public function open($savePath, $sessionName)
{
}
public function close()
{
}
public function read($id)
{
}
public function write($id, $data)
{
}
public function destroy($id)
{
}
public function gc($maxlifetime)
{
} }
} }

View File

@ -0,0 +1,124 @@
<?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;
use Symfony\Component\HttpFoundation\Session\Storage\Handler\NativeSessionHandler;
use Symfony\Component\HttpFoundation\Session\Storage\PhpBridgeSessionStorage;
use Symfony\Component\HttpFoundation\Session\Attribute\AttributeBag;
/**
* Test class for PhpSessionStorage.
*
* @author Drak <drak@zikula.org>
*
* These tests require separate processes.
*
* @runTestsInSeparateProcesses
*/
class PhpSessionStorageTest extends \PHPUnit_Framework_TestCase
{
private $savePath;
protected function setUp()
{
ini_set('session.save_handler', 'files');
ini_set('session.save_path', $this->savePath = sys_get_temp_dir().'/sf2test');
if (!is_dir($this->savePath)) {
mkdir($this->savePath);
}
}
protected function tearDown()
{
session_write_close();
array_map('unlink', glob($this->savePath.'/*'));
if (is_dir($this->savePath)) {
rmdir($this->savePath);
}
$this->savePath = null;
}
/**
* @return PhpBridgeSessionStorage
*/
protected function getStorage()
{
$storage = new PhpBridgeSessionStorage();
$storage->registerBag(new AttributeBag);
return $storage;
}
public function testPhpSession53()
{
if (version_compare(phpversion(), '5.4.0', '>=')) {
$this->markTestSkipped('Test skipped, for PHP 5.3 only.');
}
$storage = $this->getStorage();
$this->assertFalse(isset($_SESSION));
$this->assertFalse($storage->getSaveHandler()->isActive());
session_start();
$this->assertTrue(isset($_SESSION));
// in PHP 5.3 we cannot reliably tell if a session has started
$this->assertFalse($storage->getSaveHandler()->isActive());
// PHP session might have started, but the storage driver has not, so false is correct here
$this->assertFalse($storage->isStarted());
$key = $storage->getMetadataBag()->getStorageKey();
$this->assertFalse(isset($_SESSION[$key]));
$storage->start();
$this->assertTrue(isset($_SESSION[$key]));
}
public function testPhpSession54()
{
if (version_compare(phpversion(), '5.4.0', '<')) {
$this->markTestSkipped('Test skipped, for PHP 5.4 only.');
}
$storage = $this->getStorage();
$this->assertFalse(isset($_SESSION));
$this->assertFalse($storage->getSaveHandler()->isActive());
$this->assertFalse($storage->isStarted());
session_start();
$this->assertTrue(isset($_SESSION));
// in PHP 5.4 we can reliably detect a session started
$this->assertTrue($storage->getSaveHandler()->isActive());
// PHP session might have started, but the storage driver has not, so false is correct here
$this->assertFalse($storage->isStarted());
$key = $storage->getMetadataBag()->getStorageKey();
$this->assertFalse(isset($_SESSION[$key]));
$storage->start();
$this->assertTrue(isset($_SESSION[$key]));
}
public function testClear()
{
$storage = $this->getStorage();
session_start();
$_SESSION['drak'] = 'loves symfony';
$storage->getBag('attributes')->set('symfony', 'greatness');
$key = $storage->getBag('attributes')->getStorageKey();
$this->assertEquals($_SESSION[$key], array('symfony' => 'greatness'));
$this->assertEquals($_SESSION['drak'], 'loves symfony');
$storage->clear();
$this->assertEquals($_SESSION[$key], array());
$this->assertEquals($_SESSION['drak'], 'loves symfony');
}
}

View File

@ -86,19 +86,54 @@ class AbstractProxyTest extends \PHPUnit_Framework_TestCase
$this->assertFalse($this->proxy->isWrapper()); $this->assertFalse($this->proxy->isWrapper());
} }
public function testIsActive() public function testIsActivePhp53()
{ {
if (version_compare(phpversion(), '5.4.0', '>=')) {
$this->markTestSkipped('Test skipped, for PHP 5.3 only.');
}
$this->assertFalse($this->proxy->isActive()); $this->assertFalse($this->proxy->isActive());
} }
public function testSetActive() /**
* @runInSeparateProcess
*/
public function testIsActivePhp54()
{ {
if (version_compare(phpversion(), '5.4.0', '<')) {
$this->markTestSkipped('Test skipped, for PHP 5.4 only.');
}
$this->assertFalse($this->proxy->isActive());
session_start();
$this->assertTrue($this->proxy->isActive());
}
public function testSetActivePhp53()
{
if (version_compare(phpversion(), '5.4.0', '>=')) {
$this->markTestSkipped('Test skipped, for PHP 5.3 only.');
}
$this->proxy->setActive(true); $this->proxy->setActive(true);
$this->assertTrue($this->proxy->isActive()); $this->assertTrue($this->proxy->isActive());
$this->proxy->setActive(false); $this->proxy->setActive(false);
$this->assertFalse($this->proxy->isActive()); $this->assertFalse($this->proxy->isActive());
} }
/**
* @runInSeparateProcess
* @expectedException \LogicException
*/
public function testSetActivePhp54()
{
if (version_compare(phpversion(), '5.4.0', '<')) {
$this->markTestSkipped('Test skipped, for PHP 5.4 only.');
}
$this->proxy->setActive(true);
}
/** /**
* @runInSeparateProcess * @runInSeparateProcess
*/ */
@ -113,12 +148,30 @@ class AbstractProxyTest extends \PHPUnit_Framework_TestCase
/** /**
* @expectedException \LogicException * @expectedException \LogicException
*/ */
public function testNameException() public function testNameExceptionPhp53()
{ {
if (version_compare(phpversion(), '5.4.0', '>=')) {
$this->markTestSkipped('Test skipped, for PHP 5.3 only.');
}
$this->proxy->setActive(true); $this->proxy->setActive(true);
$this->proxy->setName('foo'); $this->proxy->setName('foo');
} }
/**
* @runInSeparateProcess
* @expectedException \LogicException
*/
public function testNameExceptionPhp54()
{
if (version_compare(phpversion(), '5.4.0', '<')) {
$this->markTestSkipped('Test skipped, for PHP 5.4 only.');
}
session_start();
$this->proxy->setName('foo');
}
/** /**
* @runInSeparateProcess * @runInSeparateProcess
*/ */
@ -133,9 +186,27 @@ class AbstractProxyTest extends \PHPUnit_Framework_TestCase
/** /**
* @expectedException \LogicException * @expectedException \LogicException
*/ */
public function testIdException() public function testIdExceptionPhp53()
{ {
if (version_compare(phpversion(), '5.4.0', '>=')) {
$this->markTestSkipped('Test skipped, for PHP 5.3 only.');
}
$this->proxy->setActive(true); $this->proxy->setActive(true);
$this->proxy->setId('foo'); $this->proxy->setId('foo');
} }
/**
* @runInSeparateProcess
* @expectedException \LogicException
*/
public function testIdExceptionPhp54()
{
if (version_compare(phpversion(), '5.4.0', '<')) {
$this->markTestSkipped('Test skipped, for PHP 5.4 only.');
}
session_start();
$this->proxy->setId('foo');
}
} }

View File

@ -23,7 +23,7 @@ use Symfony\Component\HttpFoundation\Session\Storage\Proxy\SessionHandlerProxy;
class SessionHandlerProxyTest extends \PHPUnit_Framework_TestCase class SessionHandlerProxyTest extends \PHPUnit_Framework_TestCase
{ {
/** /**
* @var PHPUnit_Framework_MockObject_Matcher * @var \PHPUnit_Framework_MockObject_Matcher
*/ */
private $mock; private $mock;
@ -52,7 +52,11 @@ class SessionHandlerProxyTest extends \PHPUnit_Framework_TestCase
$this->assertFalse($this->proxy->isActive()); $this->assertFalse($this->proxy->isActive());
$this->proxy->open('name', 'id'); $this->proxy->open('name', 'id');
$this->assertTrue($this->proxy->isActive()); if (version_compare(phpversion(), '5.4.0', '<')) {
$this->assertTrue($this->proxy->isActive());
} else {
$this->assertFalse($this->proxy->isActive());
}
} }
public function testOpenFalse() public function testOpenFalse()