Skip to content

Commit c21c53a

Browse files
committed
merged branch drak/start_on_demand (PR #7576)
This PR was merged into the master branch. Discussion ---------- [2.3][Session] Give greater control over how and when session starts | Q | A | ------------- | --- | Bug fix? | no | New feature? | yes | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | na | License | MIT | Doc PR | symfony/symfony-docs#2475 Refs #6036 Gives control over how start on demand works: allowing to turn it on or off and to allow bag access when session is off. Commits ------- f431cb0 Fix tests 1f521d8 Coding standards 2583c26 [HttpFoundation][FrameworkBundle] Keep save auto_start behaviour as in 2.2 and make component values consistent with FrameworkBundle's configuration options. ceaf69b [FrameworkBundle] Use more sophisticated validation and configuration. af0a140 [FrameworkBundle] Add configuration to allow control over session start on demand. 8fc2397 [HttpFoundation] Give control over how session start on demand.
2 parents 57eacea + 5dd7a3a commit c21c53a

19 files changed

+187
-67
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ CHANGELOG
44
2.3.0
55

66
* `UploadedFile::isValid` now returns false if the file was not uploaded via HTTP (in a non-test mode)
7+
* added control for session start on demand.
78

89
2.2.0
910
-----

Session/Session.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ class Session implements SessionInterface, \IteratorAggregate, \Countable
4949
/**
5050
* Constructor.
5151
*
52-
* @param SessionStorageInterface $storage A SessionStorageInterface instance.
52+
* @param SessionStorageInterface $storage A SessionStorageInterface instance
5353
* @param AttributeBagInterface $attributes An AttributeBagInterface instance, (defaults null for default AttributeBag)
5454
* @param FlashBagInterface $flashes A FlashBagInterface instance (defaults null for default FlashBag)
5555
*/

Session/SessionBagInterface.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ public function getStorageKey();
4242
/**
4343
* Clears out data from bag.
4444
*
45-
* @return mixed Whatever data was contained.
45+
* @return mixed Whatever data was contained
4646
*/
4747
public function clear();
4848
}

Session/SessionInterface.php

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,9 @@ interface SessionInterface
2323
/**
2424
* Starts the session storage.
2525
*
26-
* @return Boolean True if session started.
26+
* @return Boolean True if session started
2727
*
28-
* @throws \RuntimeException If session fails to start.
28+
* @throws \RuntimeException If session fails to start
2929
*
3030
* @api
3131
*/
@@ -34,7 +34,7 @@ public function start();
3434
/**
3535
* Returns the session ID.
3636
*
37-
* @return string The session ID.
37+
* @return string The session ID
3838
*
3939
* @api
4040
*/
@@ -52,7 +52,7 @@ public function setId($id);
5252
/**
5353
* Returns the session name.
5454
*
55-
* @return mixed The session name.
55+
* @return mixed The session name
5656
*
5757
* @api
5858
*/
@@ -76,9 +76,9 @@ public function setName($name);
7676
* @param integer $lifetime Sets the cookie lifetime for the session cookie. A null value
7777
* will leave the system settings unchanged, 0 sets the cookie
7878
* to expire with browser session. Time is in seconds, and is
79-
* not a Unix timestamp.
79+
* not a Unix timestamp
8080
*
81-
* @return Boolean True if session invalidated, false if error.
81+
* @return Boolean True if session invalidated, false if error
8282
*
8383
* @api
8484
*/
@@ -92,9 +92,9 @@ public function invalidate($lifetime = null);
9292
* @param integer $lifetime Sets the cookie lifetime for the session cookie. A null value
9393
* will leave the system settings unchanged, 0 sets the cookie
9494
* to expire with browser session. Time is in seconds, and is
95-
* not a Unix timestamp.
95+
* not a Unix timestamp
9696
*
97-
* @return Boolean True if session migrated, false if error.
97+
* @return Boolean True if session migrated, false if error
9898
*
9999
* @api
100100
*/

Session/Storage/Handler/MemcacheSessionHandler.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ class MemcacheSessionHandler implements \SessionHandlerInterface
2929
private $ttl;
3030

3131
/**
32-
* @var string Key prefix for shared environments.
32+
* @var string Key prefix for shared environments
3333
*/
3434
private $prefix;
3535

Session/Storage/Handler/MemcachedSessionHandler.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ class MemcachedSessionHandler implements \SessionHandlerInterface
3434
private $ttl;
3535

3636
/**
37-
* @var string Key prefix for shared environments.
37+
* @var string Key prefix for shared environments
3838
*/
3939
private $prefix;
4040

Session/Storage/Handler/MongoDbSessionHandler.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,11 @@ class MongoDbSessionHandler implements \SessionHandlerInterface
5252
public function __construct($mongo, array $options)
5353
{
5454
if (!($mongo instanceof \MongoClient || $mongo instanceof \Mongo)) {
55-
throw new \InvalidArgumentException('MongoClient or Mongo instance required');
55+
throw new \InvalidArgumentException('MongoClient or Mongo instance required.');
5656
}
5757

5858
if (!isset($options['database']) || !isset($options['collection'])) {
59-
throw new \InvalidArgumentException('You must provide the "database" and "collection" option for MongoDBSessionHandler');
59+
throw new \InvalidArgumentException('You must provide the "database" and "collection" option for MongoDBSessionHandler.');
6060
}
6161

6262
$this->mongo = $mongo;

Session/Storage/Handler/NativeFileSessionHandler.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,10 @@ class NativeFileSessionHandler extends NativeSessionHandler
2424
* Constructor.
2525
*
2626
* @param string $savePath Path of directory to save session files.
27-
* Default null will leave setting as defined by PHP.
27+
* Default null will leave setting as defined by PHP
2828
* '/path', 'N;/path', or 'N;octal-mode;/path
2929
*
30-
* @see http://php.net/session.configuration.php#ini.session.save-path for further details.
30+
* @see http://php.net/session.configuration.php#ini.session.save-path for further details
3131
*
3232
* @throws \InvalidArgumentException On invalid $savePath
3333
*/
@@ -41,7 +41,7 @@ public function __construct($savePath = null)
4141

4242
if ($count = substr_count($savePath, ';')) {
4343
if ($count > 2) {
44-
throw new \InvalidArgumentException(sprintf('Invalid argument $savePath \'%s\'', $savePath));
44+
throw new \InvalidArgumentException(sprintf('Invalid argument $savePath \'%s\'.', $savePath));
4545
}
4646

4747
// characters after last ';' are the path

Session/Storage/Handler/PdoSessionHandler.php

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,12 @@
2020
class PdoSessionHandler implements \SessionHandlerInterface
2121
{
2222
/**
23-
* @var \PDO PDO instance.
23+
* @var \PDO PDO instance
2424
*/
2525
private $pdo;
2626

2727
/**
28-
* @var array Database options.
28+
* @var array Database options
2929
*/
3030
private $dbOptions;
3131

@@ -90,7 +90,7 @@ public function destroy($id)
9090
$stmt->bindParam(':id', $id, \PDO::PARAM_STR);
9191
$stmt->execute();
9292
} catch (\PDOException $e) {
93-
throw new \RuntimeException(sprintf('PDOException was thrown when trying to manipulate session data: %s', $e->getMessage()), 0, $e);
93+
throw new \RuntimeException(sprintf('PDOException was thrown when trying to manipulate session data: %s.', $e->getMessage()), 0, $e);
9494
}
9595

9696
return true;
@@ -113,7 +113,7 @@ public function gc($lifetime)
113113
$stmt->bindValue(':time', time() - $lifetime, \PDO::PARAM_INT);
114114
$stmt->execute();
115115
} catch (\PDOException $e) {
116-
throw new \RuntimeException(sprintf('PDOException was thrown when trying to manipulate session data: %s', $e->getMessage()), 0, $e);
116+
throw new \RuntimeException(sprintf('PDOException was thrown when trying to manipulate session data: %s.', $e->getMessage()), 0, $e);
117117
}
118118

119119
return true;
@@ -149,7 +149,7 @@ public function read($id)
149149

150150
return '';
151151
} catch (\PDOException $e) {
152-
throw new \RuntimeException(sprintf('PDOException was thrown when trying to read the session data: %s', $e->getMessage()), 0, $e);
152+
throw new \RuntimeException(sprintf('PDOException was thrown when trying to read the session data: %s.', $e->getMessage()), 0, $e);
153153
}
154154
}
155155

@@ -204,7 +204,7 @@ public function write($id, $data)
204204
}
205205
}
206206
} catch (\PDOException $e) {
207-
throw new \RuntimeException(sprintf('PDOException was thrown when trying to write the session data: %s', $e->getMessage()), 0, $e);
207+
throw new \RuntimeException(sprintf('PDOException was thrown when trying to write the session data: %s.', $e->getMessage()), 0, $e);
208208
}
209209

210210
return true;
@@ -216,7 +216,7 @@ public function write($id, $data)
216216
* @param string $id
217217
* @param string $data
218218
*
219-
* @return boolean True.
219+
* @return boolean True
220220
*/
221221
private function createNewSession($id, $data = '')
222222
{

Session/Storage/MetadataBag.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ class MetadataBag implements SessionBagInterface
5151
/**
5252
* Constructor.
5353
*
54-
* @param string $storageKey The key used to store bag in the session.
54+
* @param string $storageKey The key used to store bag in the session
5555
*/
5656
public function __construct($storageKey = '_sf2_meta')
5757
{
@@ -90,7 +90,7 @@ public function getLifetime()
9090
* @param integer $lifetime Sets the cookie lifetime for the session cookie. A null value
9191
* will leave the system settings unchanged, 0 sets the cookie
9292
* to expire with browser session. Time is in seconds, and is
93-
* not a Unix timestamp.
93+
* not a Unix timestamp
9494
*/
9595
public function stampNew($lifetime = null)
9696
{

Session/Storage/MockArraySessionStorage.php

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,16 +63,23 @@ class MockArraySessionStorage implements SessionStorageInterface
6363
*/
6464
protected $bags;
6565

66+
/**
67+
* @var Boolean
68+
*/
69+
protected $mode;
70+
6671
/**
6772
* Constructor.
6873
*
6974
* @param string $name Session name
70-
* @param MetadataBag $metaBag MetadataBag instance.
75+
* @param MetadataBag $metaBag MetadataBag instance
76+
* @param integer $mode Session on demand mode
7177
*/
72-
public function __construct($name = 'MOCKSESSID', MetadataBag $metaBag = null)
78+
public function __construct($name = 'MOCKSESSID', MetadataBag $metaBag = null, $mode = self::START_ON_DEMAND)
7379
{
7480
$this->name = $name;
7581
$this->setMetadataBag($metaBag);
82+
$this->mode = $mode;
7683
}
7784

7885
/**
@@ -160,7 +167,7 @@ public function setName($name)
160167
public function save()
161168
{
162169
if (!$this->started || $this->closed) {
163-
throw new \RuntimeException("Trying to save a session that was not started yet or was already closed");
170+
throw new \RuntimeException("Trying to save a session that was not started yet or was already closed.");
164171
}
165172
// nothing to do since we don't persist the session data
166173
$this->closed = false;
@@ -200,8 +207,10 @@ public function getBag($name)
200207
throw new \InvalidArgumentException(sprintf('The SessionBagInterface %s is not registered.', $name));
201208
}
202209

203-
if (!$this->started) {
210+
if (!$this->started && self::START_ON_DEMAND === $this->mode) {
204211
$this->start();
212+
} elseif (!$this->started && self::NO_START_ON_DEMAND_STRICT === $this->mode) {
213+
throw new \RuntimeException('Cannot access session bags because the session has not been started.');
205214
}
206215

207216
return $this->bags[$name];

Session/Storage/MockFileSessionStorage.php

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -29,19 +29,15 @@ class MockFileSessionStorage extends MockArraySessionStorage
2929
*/
3030
private $savePath;
3131

32-
/**
33-
* @var array
34-
*/
35-
private $sessionData;
36-
3732
/**
3833
* Constructor.
3934
*
40-
* @param string $savePath Path of directory to save session files.
41-
* @param string $name Session name.
42-
* @param MetadataBag $metaBag MetadataBag instance.
35+
* @param string $savePath Path of directory to save session files
36+
* @param string $name Session name
37+
* @param MetadataBag $metaBag MetadataBag instance
38+
* @param integer $mode Start on demand mode
4339
*/
44-
public function __construct($savePath = null, $name = 'MOCKSESSID', MetadataBag $metaBag = null)
40+
public function __construct($savePath = null, $name = 'MOCKSESSID', MetadataBag $metaBag = null, $mode = self::START_ON_DEMAND)
4541
{
4642
if (null === $savePath) {
4743
$savePath = sys_get_temp_dir();
@@ -53,7 +49,7 @@ public function __construct($savePath = null, $name = 'MOCKSESSID', MetadataBag
5349

5450
$this->savePath = $savePath;
5551

56-
parent::__construct($name, $metaBag);
52+
parent::__construct($name, $metaBag, $mode);
5753
}
5854

5955
/**
@@ -98,7 +94,7 @@ public function regenerate($destroy = false, $lifetime = null)
9894
public function save()
9995
{
10096
if (!$this->started) {
101-
throw new \RuntimeException("Trying to save a session that was not started yet or was already closed");
97+
throw new \RuntimeException("Trying to save a session that was not started yet or was already closed.");
10298
}
10399

104100
file_put_contents($this->getFilePath(), serialize($this->data));

Session/Storage/NativeSessionStorage.php

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -52,15 +52,26 @@ class NativeSessionStorage implements SessionStorageInterface
5252
*/
5353
protected $metadataBag;
5454

55+
/**
56+
* @var Boolean
57+
*/
58+
protected $mode;
59+
60+
/**
61+
* @var Boolean
62+
*/
63+
protected $emulatePhp;
64+
5565
/**
5666
* Constructor.
5767
*
5868
* Depending on how you want the storage driver to behave you probably
5969
* want to override this constructor entirely.
6070
*
6171
* List of options for $options array with their defaults.
72+
*
6273
* @see http://php.net/session.configuration for options
63-
* but we omit 'session.' from the beginning of the keys for convenience.
74+
* but we omit 'session.' from the beginning of the keys for convenience.
6475
*
6576
* ("auto_start", is not supported as it tells PHP to start a session before
6677
* PHP starts to execute user-land code. Setting during runtime has no effect).
@@ -92,11 +103,12 @@ class NativeSessionStorage implements SessionStorageInterface
92103
* upload_progress.min-freq, "1"
93104
* url_rewriter.tags, "a=href,area=href,frame=src,form=,fieldset="
94105
*
95-
* @param array $options Session configuration options.
106+
* @param array $options Session configuration options
96107
* @param AbstractProxy|NativeSessionHandler|\SessionHandlerInterface|null $handler
97-
* @param MetadataBag $metaBag MetadataBag.
108+
* @param MetadataBag $metaBag MetadataBag
109+
* @param integer $mode Start on demand mode
98110
*/
99-
public function __construct(array $options = array(), $handler = null, MetadataBag $metaBag = null)
111+
public function __construct(array $options = array(), $handler = null, MetadataBag $metaBag = null, $mode = self::START_ON_DEMAND)
100112
{
101113
ini_set('session.cache_limiter', ''); // disable by default because it's managed by HeaderBag (if used)
102114
ini_set('session.use_cookies', 1);
@@ -110,6 +122,7 @@ public function __construct(array $options = array(), $handler = null, MetadataB
110122
$this->setMetadataBag($metaBag);
111123
$this->setOptions($options);
112124
$this->setSaveHandler($handler);
125+
$this->mode = $mode;
113126
}
114127

115128
/**
@@ -146,7 +159,7 @@ public function start()
146159

147160
// ok to try and start the session
148161
if (!session_start()) {
149-
throw new \RuntimeException('Failed to start the session');
162+
throw new \RuntimeException('Failed to start the session.');
150163
}
151164

152165
$this->loadSession();
@@ -259,10 +272,10 @@ public function getBag($name)
259272
throw new \InvalidArgumentException(sprintf('The SessionBagInterface %s is not registered.', $name));
260273
}
261274

262-
if ($this->saveHandler->isActive() && !$this->started) {
263-
$this->loadSession();
264-
} elseif (!$this->started) {
275+
if (!$this->started && self::START_ON_DEMAND === $this->mode) {
265276
$this->start();
277+
} elseif (!$this->started && self::NO_START_ON_DEMAND_STRICT === $this->mode) {
278+
throw new \RuntimeException('Cannot access session bags because the session has not been started.');
266279
}
267280

268281
return $this->bags[$name];
@@ -306,7 +319,7 @@ public function isStarted()
306319
* For convenience we omit 'session.' from the beginning of the keys.
307320
* Explicitly ignores other ini keys.
308321
*
309-
* @param array $options Session ini directives array(key => value).
322+
* @param array $options Session ini directives array(key => value)
310323
*
311324
* @see http://php.net/session.configuration
312325
*/

0 commit comments

Comments
 (0)