Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit51fc454

Browse files
[HttpFoundation] Allow dynamic session "ttl" when using a remote storage
1 parent9a14dd0 commit51fc454

File tree

11 files changed

+74
-18
lines changed

11 files changed

+74
-18
lines changed

‎src/Symfony/Bundle/FrameworkBundle/Resources/config/session.php‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@
7777

7878
->set('session.abstract_handler', AbstractSessionHandler::class)
7979
->factory([SessionHandlerFactory::class,'createHandler'])
80-
->args([abstract_arg('A string or a connection object')])
80+
->args([abstract_arg('A string or a connection object'), []])
8181

8282
->set('session_listener', SessionListener::class)
8383
->args([

‎src/Symfony/Component/HttpFoundation/CHANGELOG.md‎

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

77
* Add stale while revalidate and stale if error cache header
8+
* Allow dynamic session "ttl" when using a remote storage
89

910
6.0
1011
---

‎src/Symfony/Component/HttpFoundation/Session/Storage/Handler/MemcachedSessionHandler.php‎

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ class MemcachedSessionHandler extends AbstractSessionHandler
2626
/**
2727
* Time to live in seconds.
2828
*/
29-
private?int$ttl;
29+
privateint|\Closure|null$ttl;
3030

3131
/**
3232
* Key prefix for shared environments.
@@ -69,7 +69,8 @@ protected function doRead(string $sessionId): string
6969

7070
publicfunctionupdateTimestamp(string$sessionId,string$data):bool
7171
{
72-
$this->memcached->touch($this->prefix.$sessionId,time() + (int) ($this->ttl ??ini_get('session.gc_maxlifetime')));
72+
$ttl = ($this->ttlinstanceof \Closure ? ($this->ttl)() :$this->ttl) ??ini_get('session.gc_maxlifetime');
73+
$this->memcached->touch($this->prefix.$sessionId,time() + (int)$ttl);
7374

7475
returntrue;
7576
}
@@ -79,7 +80,9 @@ public function updateTimestamp(string $sessionId, string $data): bool
7980
*/
8081
protectedfunctiondoWrite(string$sessionId,string$data):bool
8182
{
82-
return$this->memcached->set($this->prefix.$sessionId,$data,time() + (int) ($this->ttl ??ini_get('session.gc_maxlifetime')));
83+
$ttl = ($this->ttlinstanceof \Closure ? ($this->ttl)() :$this->ttl) ??ini_get('session.gc_maxlifetime');
84+
85+
return$this->memcached->set($this->prefix.$sessionId,$data,time() + (int)$ttl);
8386
}
8487

8588
/**

‎src/Symfony/Component/HttpFoundation/Session/Storage/Handler/MongoDbSessionHandler.php‎

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ class MongoDbSessionHandler extends AbstractSessionHandler
2929
privateClient$mongo;
3030
privateCollection$collection;
3131
privatearray$options;
32+
privateint|\Closure|null$ttl;
3233

3334
/**
3435
* Constructor.
@@ -39,7 +40,8 @@ class MongoDbSessionHandler extends AbstractSessionHandler
3940
* * id_field: The field name for storing the session id [default: _id]
4041
* * data_field: The field name for storing the session data [default: data]
4142
* * time_field: The field name for storing the timestamp [default: time]
42-
* * expiry_field: The field name for storing the expiry-timestamp [default: expires_at].
43+
* * expiry_field: The field name for storing the expiry-timestamp [default: expires_at]
44+
* * ttl: The time to live in seconds.
4345
*
4446
* It is strongly recommended to put an index on the `expiry_field` for
4547
* garbage-collection. Alternatively it's possible to automatically expire
@@ -74,6 +76,7 @@ public function __construct(Client $mongo, array $options)
7476
'time_field' =>'time',
7577
'expiry_field' =>'expires_at',
7678
],$options);
79+
$this->ttl =$this->options['ttl'] ??null;
7780
}
7881

7982
publicfunctionclose():bool
@@ -105,7 +108,8 @@ public function gc(int $maxlifetime): int|false
105108
*/
106109
protectedfunctiondoWrite(string$sessionId,string$data):bool
107110
{
108-
$expiry =newUTCDateTime((time() + (int)ini_get('session.gc_maxlifetime')) *1000);
111+
$ttl = ($this->ttlinstanceof \Closure ? ($this->ttl)() :$this->ttl) ??ini_get('session.gc_maxlifetime');
112+
$expiry =newUTCDateTime((time() + (int)$ttl) *1000);
109113

110114
$fields = [
111115
$this->options['time_field'] =>newUTCDateTime(),
@@ -124,7 +128,8 @@ protected function doWrite(string $sessionId, string $data): bool
124128

125129
publicfunctionupdateTimestamp(string$sessionId,string$data):bool
126130
{
127-
$expiry =newUTCDateTime((time() + (int)ini_get('session.gc_maxlifetime')) *1000);
131+
$ttl = ($this->ttlinstanceof \Closure ? ($this->ttl)() :$this->ttl) ??ini_get('session.gc_maxlifetime');
132+
$expiry =newUTCDateTime((time() + (int)$ttl) *1000);
128133

129134
$this->getCollection()->updateOne(
130135
[$this->options['id_field'] =>$sessionId],

‎src/Symfony/Component/HttpFoundation/Session/Storage/Handler/PdoSessionHandler.php‎

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,11 @@ class PdoSessionHandler extends AbstractSessionHandler
7979
privatestring$lifetimeCol ='sess_lifetime';
8080
privatestring$timeCol ='sess_time';
8181

82+
/**
83+
* Time to live in seconds.
84+
*/
85+
privateint|\Closure|null$ttl;
86+
8287
/**
8388
* Username when lazy-connect.
8489
*/
@@ -137,6 +142,7 @@ class PdoSessionHandler extends AbstractSessionHandler
137142
* * db_password: The password when lazy-connect [default: '']
138143
* * db_connection_options: An array of driver-specific connection options [default: []]
139144
* * lock_mode: The strategy for locking, see constants [default: LOCK_TRANSACTIONAL]
145+
* * ttl: The time to live in seconds.
140146
*
141147
* @param \PDO|string|null $pdoOrDsn A \PDO instance or DSN string or URL string or null
142148
*
@@ -166,6 +172,7 @@ public function __construct(\PDO|string $pdoOrDsn = null, array $options = [])
166172
$this->password =$options['db_password'] ??$this->password;
167173
$this->connectionOptions =$options['db_connection_options'] ??$this->connectionOptions;
168174
$this->lockMode =$options['lock_mode'] ??$this->lockMode;
175+
$this->ttl =$options['ttl'] ??null;
169176
}
170177

171178
/**
@@ -275,7 +282,7 @@ protected function doDestroy(string $sessionId): bool
275282
*/
276283
protectedfunctiondoWrite(string$sessionId,string$data):bool
277284
{
278-
$maxlifetime = (int)ini_get('session.gc_maxlifetime');
285+
$maxlifetime = (int)(($this->ttlinstanceof \Closure ? ($this->ttl)() :$this->ttl) ??ini_get('session.gc_maxlifetime'));
279286

280287
try {
281288
// We use a single MERGE SQL query when supported by the database.
@@ -318,7 +325,7 @@ protected function doWrite(string $sessionId, string $data): bool
318325

319326
publicfunctionupdateTimestamp(string$sessionId,string$data):bool
320327
{
321-
$expiry =time() + (int)ini_get('session.gc_maxlifetime');
328+
$expiry =time() + (int)(($this->ttlinstanceof \Closure ? ($this->ttl)() :$this->ttl) ??ini_get('session.gc_maxlifetime'));
322329

323330
try {
324331
$updateStmt =$this->pdo->prepare(

‎src/Symfony/Component/HttpFoundation/Session/Storage/Handler/RedisSessionHandler.php‎

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ class RedisSessionHandler extends AbstractSessionHandler
3333
/**
3434
* Time to live in seconds.
3535
*/
36-
private?int$ttl;
36+
privateint|\Closure|null$ttl;
3737

3838
/**
3939
* List of available options:
@@ -66,7 +66,8 @@ protected function doRead(string $sessionId): string
6666
*/
6767
protectedfunctiondoWrite(string$sessionId,string$data):bool
6868
{
69-
$result =$this->redis->setEx($this->prefix.$sessionId, (int) ($this->ttl ??ini_get('session.gc_maxlifetime')),$data);
69+
$ttl = ($this->ttlinstanceof \Closure ? ($this->ttl)() :$this->ttl) ??ini_get('session.gc_maxlifetime');
70+
$result =$this->redis->setEx($this->prefix.$sessionId, (int)$ttl,$data);
7071

7172
return$result && !$resultinstanceof ErrorInterface;
7273
}
@@ -109,6 +110,8 @@ public function gc(int $maxlifetime): int|false
109110

110111
publicfunctionupdateTimestamp(string$sessionId,string$data):bool
111112
{
112-
return$this->redis->expire($this->prefix.$sessionId, (int) ($this->ttl ??ini_get('session.gc_maxlifetime')));
113+
$ttl = ($this->ttlinstanceof \Closure ? ($this->ttl)() :$this->ttl) ??ini_get('session.gc_maxlifetime');
114+
115+
return$this->redis->expire($this->prefix.$sessionId, (int)$ttl);
113116
}
114117
}

‎src/Symfony/Component/HttpFoundation/Session/Storage/Handler/SessionHandlerFactory.php‎

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,16 @@
2121
*/
2222
class SessionHandlerFactory
2323
{
24-
publicstaticfunctioncreateHandler(object|string$connection):AbstractSessionHandler
24+
publicstaticfunctioncreateHandler(object|string$connection,array$options = []):AbstractSessionHandler
2525
{
26-
if ($options =\is_string($connection) ?parse_url($connection) :false) {
27-
parse_str($options['query'] ??'',$options);
26+
if ($query =\is_string($connection) ?parse_url($connection) :false) {
27+
parse_str($query['query'] ??'',$query);
28+
29+
if (($options['ttl'] ??null)instanceof \Closure) {
30+
$query['ttl'] =$options['ttl'];
31+
}
2832
}
33+
$options = ($query ?: []) +$options;
2934

3035
switch (true) {
3136
case$connectioninstanceof \Redis:
@@ -58,7 +63,7 @@ public static function createHandler(object|string $connection): AbstractSession
5863
$handlerClass =str_starts_with($connection,'memcached:') ? MemcachedSessionHandler::class : RedisSessionHandler::class;
5964
$connection = AbstractAdapter::createConnection($connection, ['lazy' =>true]);
6065

61-
returnnew$handlerClass($connection,array_intersect_key($options ?: [], ['prefix' =>1,'ttl' =>1]));
66+
returnnew$handlerClass($connection,array_intersect_key($options, ['prefix' =>1,'ttl' =>1]));
6267

6368
casestr_starts_with($connection,'pdo_oci://'):
6469
if (!class_exists(DriverManager::class)) {
@@ -76,7 +81,7 @@ public static function createHandler(object|string $connection): AbstractSession
7681
casestr_starts_with($connection,'sqlsrv://'):
7782
casestr_starts_with($connection,'sqlite://'):
7883
casestr_starts_with($connection,'sqlite3://'):
79-
returnnewPdoSessionHandler($connection,$options ?: []);
84+
returnnewPdoSessionHandler($connection,$options);
8085
}
8186

8287
thrownew \InvalidArgumentException(sprintf('Unsupported Connection: "%s".',$connection));

‎src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/AbstractRedisSessionHandlerTestCase.php‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,19 @@ public function testUseTtlOption(int $ttl)
164164

165165
$this->assertLessThan($redisTtl,$ttl -5);
166166
$this->assertGreaterThan($redisTtl,$ttl +5);
167+
168+
$options = [
169+
'prefix' =>self::PREFIX,
170+
'ttl' =>fn () =>$ttl,
171+
];
172+
173+
$handler =newRedisSessionHandler($this->redisClient,$options);
174+
$handler->write('id','data');
175+
$redisTtl =$this->redisClient->ttl(self::PREFIX.'id');
176+
177+
$this->assertLessThan($redisTtl,$ttl -5);
178+
$this->assertGreaterThan($redisTtl,$ttl +5);
179+
167180
}
168181

169182
publicfunctiongetTtlFixtures():array

‎src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/MemcachedSessionHandlerTest.php‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ public function getOptionFixtures()
134134
return [
135135
[['prefix' =>'session'],true],
136136
[['expiretime' =>100],true],
137-
[['prefix' =>'session','expiretime' =>200],true],
137+
[['prefix' =>'session','ttl' =>200],true],
138138
[['expiretime' =>100,'foo' =>'bar'],false],
139139
];
140140
}

‎src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/PdoSessionHandlerTest.php‎

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,21 @@ public function provideUrlDsnPairs()
345345
yield ['mssql://localhost:56/test','sqlsrv:server=localhost,56;Database=test'];
346346
}
347347

348+
publicfunctiontestTtl()
349+
{
350+
foreach ([60,fn () =>60]as$ttl) {
351+
$pdo =$this->getMemorySqlitePdo();
352+
$storage =newPdoSessionHandler($pdo, ['ttl' =>$ttl]);
353+
354+
$storage->open('','sid');
355+
$storage->read('id');
356+
$storage->write('id','data');
357+
$storage->close();
358+
359+
$this->assertEqualsWithDelta(time() +60,$pdo->query('SELECT sess_lifetime FROM sessions')->fetchColumn(),5);
360+
}
361+
}
362+
348363
/**
349364
* @return resource
350365
*/

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp