Permalink
Browse files

[HttpFoundation] Split session handler callbacks to separate object.

  • Loading branch information...
1 parent bb30a44 commit 23267077ff3c9f85e21bf972b7e84d0bfa91357b Drak committed Mar 3, 2012
@@ -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.
@@ -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);
}
/**
@@ -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.
*
@@ -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
@@ -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;
@@ -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())
{
@@ -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
@@ -49,6 +45,11 @@
*/
protected $closed = false;
+ /**
+ * @var AbstractProxy
+ */
+ protected $saveHandler;
+
/**
* Constructor.
*
@@ -75,7 +76,6 @@
* hash_function, "0"
* name, "PHPSESSID"
* referer_check, ""
- * save_path, ""
* serialize_handler, "php"
* use_cookies, "1"
* use_only_cookies, "1"
@@ -89,12 +89,23 @@
* 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;
}
/**
@@ -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;
@@ -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;
}
@@ -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'))) {
@@ -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.
@@ -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');
+ }
+ }
}
/**

0 comments on commit 2326707

Please sign in to comment.