Skip to content

Commit

Permalink
[HttpFoundation] Split session handler callbacks to separate object.
Browse files Browse the repository at this point in the history
  • Loading branch information
Drak committed Mar 14, 2012
1 parent bb30a44 commit 2326707
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 44 deletions.
Expand Up @@ -9,15 +9,15 @@
* file that was distributed with this source code.
*/

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

/**
* PdoSessionStorage.
*
* @author Fabien Potencier <fabien@symfony.com>
* @author Michael Williams <michael.williams@funsational.com>
*/
class PdoSessionStorage extends AbstractSessionStorage implements \SessionHandlerInterface
class PdoSessionHandler implements \SessionHandlerInterface
{
/**
* PDO instance.
Expand Down Expand Up @@ -58,8 +58,6 @@ public function __construct(\PDO $pdo, array $dbOptions = array(), array $option
'db_data_col' => 'sess_data',
'db_time_col' => 'sess_time',
), $dbOptions);

parent::__construct($options);
}

/**
Expand Down
Expand Up @@ -11,6 +11,8 @@

namespace Symfony\Component\HttpFoundation\Session\Storage;

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

/**
* MockArraySessionStorage mocks the session for unit tests.
*
Expand All @@ -23,7 +25,7 @@
* @author Bulat Shakirzyanov <mallluhuct@gmail.com>
* @author Drak <drak@zikula.org>
*/
class MockArraySessionStorage extends AbstractSessionStorage
class MockArraySessionStorage extends SessionStorage
{
/**
* @var string
Expand All @@ -35,6 +37,16 @@ class MockArraySessionStorage extends AbstractSessionStorage
*/
protected $sessionData = array();

public function __construct(array $options = array())
{
parent::__construct($options, new NullSessionHandler());
}

/**
* Sets the session data.
*
* @param array $array
*/
public function setSessionData(array $array)
{
$this->sessionData = $array;
Expand Down
Expand Up @@ -33,7 +33,7 @@ class MockFileSessionStorage extends MockArraySessionStorage
* @param string $savePath Path of directory to save session files.
* @param array $options Session options.
*
* @see AbstractSessionStorage::__construct()
* @see SessionStorage::__construct()
*/
public function __construct($savePath = null, array $options = array())
{
Expand Down
Expand Up @@ -12,20 +12,16 @@
namespace Symfony\Component\HttpFoundation\Session\Storage;

use Symfony\Component\HttpFoundation\Session\SessionBagInterface;
use Symfony\Component\HttpFoundation\Session\Storage\Proxy\NativeProxy;
use Symfony\Component\HttpFoundation\Session\Storage\Proxy\AbstractProxy;
use Symfony\Component\HttpFoundation\Session\Storage\Proxy\SessionHandlerProxy;

/**
* This provides a base class for session attribute storage.
*
* This can be used to implement internal PHP session handlers
* provided by PHP extensions or custom session save handlers
* implementing the \SessionHandlerInterface
*
* @see http://php.net/session.customhandler
* @see http://php.net/sessionhandlerinterface
*
* @author Drak <drak@zikula.org>
*/
abstract class AbstractSessionStorage implements SessionStorageInterface
class SessionStorage implements SessionStorageInterface
{
/**
* Array of SessionBagInterface
Expand All @@ -49,6 +45,11 @@ abstract class AbstractSessionStorage implements SessionStorageInterface
*/
protected $closed = false;

/**
* @var AbstractProxy
*/
protected $saveHandler;

/**
* Constructor.
*
Expand All @@ -75,7 +76,6 @@ abstract class AbstractSessionStorage implements SessionStorageInterface
* hash_function, "0"
* name, "PHPSESSID"
* referer_check, ""
* save_path, ""
* serialize_handler, "php"
* use_cookies, "1"
* use_only_cookies, "1"
Expand All @@ -89,12 +89,23 @@ abstract class AbstractSessionStorage implements SessionStorageInterface
* url_rewriter.tags, "a=href,area=href,frame=src,form=,fieldset="
*
* @param array $options Session configuration options.
* @param $handler SessionHandlerInterface.
*/
public function __construct(array $options = array())
public function __construct(array $options = array(), $handler = null)
{
$this->setOptions($options);
$this->registerSaveHandlers();
$this->registerShutdownFunction();

$this->setSaveHandler($handler);
}

/**
* Gets the save handler instance.
*
* @return AbstractProxy
*/
public function getSaveHandler()
{
return $this->saveHandler;
}

/**
Expand All @@ -117,6 +128,10 @@ public function start()

$this->loadSession();

if (!$this->saveHandler->isWrapper() && !$this->saveHandler->isSessionHandlerInterface()) {
$this->saveHandler->setActive(false);
}

$this->started = true;
$this->closed = false;

Expand Down Expand Up @@ -149,6 +164,11 @@ public function regenerate($destroy = false)
public function save()
{
session_write_close();

if (!$this->saveHandler->isWrapper() && !$this->getSaveHandler()->isSessionHandlerInterface()) {
$this->saveHandler->setActive(false);
}

$this->closed = true;
}

Expand Down Expand Up @@ -230,7 +250,7 @@ protected function setOptions(array $options)
'entropy_file', 'entropy_length', 'gc_divisor',
'gc_maxlifetime', 'gc_probability', 'hash_bits_per_character',
'hash_function', 'name', 'referer_check',
'save_path', 'serialize_handler', 'use_cookies',
'serialize_handler', 'use_cookies',
'use_only_cookies', 'use_trans_sid', 'upload_progress.enabled',
'upload_progress.cleanup', 'upload_progress.prefix', 'upload_progress.name',
'upload_progress.freq', 'upload_progress.min-freq', 'url_rewriter.tags'))) {
Expand All @@ -240,7 +260,7 @@ protected function setOptions(array $options)
}

/**
* Registers this storage device as a PHP session handler.
* Registers save handler as a PHP session handler.
*
* To use internal PHP session save handlers, override this method using ini_set with
* session.save_handlers and session.save_path e.g.
Expand All @@ -250,34 +270,37 @@ protected function setOptions(array $options)
*
* @see http://php.net/session-set-save-handler
* @see http://php.net/sessionhandlerinterface
* @see http://php.net/sessionhandler
*
* @param object $saveHandler
*/
protected function registerSaveHandlers()
public function setSaveHandler($saveHandler)
{
// note this can be reset to PHP's control using ini_set('session.save_handler', 'files');
// so long as ini_set() is called before the session is started.
if ($this instanceof \SessionHandlerInterface) {
session_set_save_handler(
array($this, 'open'),
array($this, 'close'),
array($this, 'read'),
array($this, 'write'),
array($this, 'destroy'),
array($this, 'gc')
);
// Wrap $saveHandler in proxy
if (!$saveHandler instanceof AbstractProxy && $saveHandler instanceof \SessionHandlerInterface) {
$saveHandler = new SessionHandlerProxy($saveHandler);
} else {
$saveHandler = new NativeProxy($saveHandler);
}
}

/**
* Registers PHP shutdown function.
*
* This method is required to avoid strange issues when using PHP objects as
* session save handlers.
*
* @see http://php.net/register-shutdown-function
*/
protected function registerShutdownFunction()
{
register_shutdown_function('session_write_close');
$this->saveHandler = $saveHandler;

if ($this->saveHandler instanceof \SessionHandlerInterface) {
if (version_compare(phpversion(), '5.4.0', '>=')) {
session_set_save_handler($this->saveHandler, true);
} else {
session_set_save_handler(
array($this->saveHandler, 'open'),
array($this->saveHandler, 'close'),
array($this->saveHandler, 'read'),
array($this->saveHandler, 'write'),
array($this->saveHandler, 'destroy'),
array($this->saveHandler, 'gc')
);

register_shutdown_function('session_write_close');
}
}
}

/**
Expand Down

0 comments on commit 2326707

Please sign in to comment.