Skip to content

Commit b64a0e2

Browse files
tvlooynicolas-grekas
authored andcommitted
Use relative timestamps
1 parent eec2141 commit b64a0e2

File tree

2 files changed

+34
-3
lines changed

2 files changed

+34
-3
lines changed

Session/Storage/Handler/MemcachedSessionHandler.php

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ protected function doRead(string $sessionId)
7777
#[\ReturnTypeWillChange]
7878
public function updateTimestamp($sessionId, $data)
7979
{
80-
$this->memcached->touch($this->prefix.$sessionId, time() + (int) ($this->ttl ?? \ini_get('session.gc_maxlifetime')));
80+
$this->memcached->touch($this->prefix.$sessionId, $this->getCompatibleTtl());
8181

8282
return true;
8383
}
@@ -87,7 +87,20 @@ public function updateTimestamp($sessionId, $data)
8787
*/
8888
protected function doWrite(string $sessionId, string $data)
8989
{
90-
return $this->memcached->set($this->prefix.$sessionId, $data, time() + (int) ($this->ttl ?? \ini_get('session.gc_maxlifetime')));
90+
return $this->memcached->set($this->prefix.$sessionId, $data, $this->getCompatibleTtl());
91+
}
92+
93+
private function getCompatibleTtl(): int
94+
{
95+
$ttl = (int) ($this->ttl ?? \ini_get('session.gc_maxlifetime'));
96+
97+
// If the relative TTL that is used exceeds 30 days, memcached will treat the value as Unix time.
98+
// We have to convert it to an absolute Unix time at this point, to make sure the TTL is correct.
99+
if ($ttl > 60 * 60 * 24 * 30) {
100+
$ttl += time();
101+
}
102+
103+
return $ttl;
91104
}
92105

93106
/**

Tests/Session/Storage/Handler/MemcachedSessionHandlerTest.php

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
/**
1818
* @requires extension memcached
19+
*
1920
* @group time-sensitive
2021
*/
2122
class MemcachedSessionHandlerTest extends TestCase
@@ -92,13 +93,30 @@ public function testWriteSession()
9293
$this->memcached
9394
->expects($this->once())
9495
->method('set')
95-
->with(self::PREFIX.'id', 'data', $this->equalTo(time() + self::TTL, 2))
96+
->with(self::PREFIX.'id', 'data', $this->equalTo(self::TTL, 2))
9697
->willReturn(true)
9798
;
9899

99100
$this->assertTrue($this->storage->write('id', 'data'));
100101
}
101102

103+
public function testWriteSessionWithLargeTTL()
104+
{
105+
$this->memcached
106+
->expects($this->once())
107+
->method('set')
108+
->with(self::PREFIX.'id', 'data', $this->equalTo(time() + self::TTL + 60 * 60 * 24 * 30, 2))
109+
->willReturn(true)
110+
;
111+
112+
$storage = new MemcachedSessionHandler(
113+
$this->memcached,
114+
['prefix' => self::PREFIX, 'expiretime' => self::TTL + 60 * 60 * 24 * 30]
115+
);
116+
117+
$this->assertTrue($storage->write('id', 'data'));
118+
}
119+
102120
public function testDestroySession()
103121
{
104122
$this->memcached

0 commit comments

Comments
 (0)