From 3459a69153a8145fc6fac459123802bd766b456d Mon Sep 17 00:00:00 2001 From: Natan Felles Date: Fri, 4 Apr 2025 18:29:37 -0300 Subject: [PATCH] Do not remove the handler object if it is created externally --- src/SaveHandler.php | 10 +++++++++ src/SaveHandlers/DatabaseHandler.php | 5 ++++- src/SaveHandlers/MemcachedHandler.php | 9 +++++--- src/SaveHandlers/RedisHandler.php | 23 ++++++++++++--------- tests/SaveHandlers/DatabaseHandlerTest.php | 2 ++ tests/SaveHandlers/MemcachedHandlerTest.php | 2 ++ tests/SaveHandlers/RedisHandlerTest.php | 2 ++ 7 files changed, 39 insertions(+), 14 deletions(-) diff --git a/src/SaveHandler.php b/src/SaveHandler.php index fa25b5a..ed6a762 100644 --- a/src/SaveHandler.php +++ b/src/SaveHandler.php @@ -60,6 +60,16 @@ abstract class SaveHandler implements \SessionHandlerInterface, \SessionUpdateTi * @var Logger|null */ protected ?Logger $logger; + /** + * It says that the handler object was set with an externally created object. + * + * If this is true, the handler object should not be changed or removed (in the close method). + * + * Some functions, such as `session_regenerate_id`, call the close method and then open again! + * + * @var bool + */ + protected bool $setByExternal = false; /** * SessionSaveHandler constructor. diff --git a/src/SaveHandlers/DatabaseHandler.php b/src/SaveHandlers/DatabaseHandler.php index cd66006..2492370 100644 --- a/src/SaveHandlers/DatabaseHandler.php +++ b/src/SaveHandlers/DatabaseHandler.php @@ -100,6 +100,7 @@ protected function prepareConfig(#[SensitiveParameter] array $config) : void public function setDatabase(Database $database) : static { + $this->setByExternal = true; $this->database = $database; return $this; } @@ -280,7 +281,9 @@ public function updateTimestamp($id, $data) : bool public function close() : bool { $closed = !($this->lockId && !$this->unlock()); - $this->database = null; + if ($this->setByExternal === false) { + $this->database = null; + } return $closed; } diff --git a/src/SaveHandlers/MemcachedHandler.php b/src/SaveHandlers/MemcachedHandler.php index 2b02732..08444b1 100644 --- a/src/SaveHandlers/MemcachedHandler.php +++ b/src/SaveHandlers/MemcachedHandler.php @@ -94,6 +94,7 @@ protected function prepareConfig(#[SensitiveParameter] array $config) : void public function setMemcached(Memcached $memcached) : static { + $this->setByExternal = true; $this->memcached = $memcached; return $this; } @@ -229,10 +230,12 @@ public function close() : bool if ($this->lockId) { $this->memcached->delete($this->lockId); } - if (!$this->memcached->quit()) { - return false; + if ($this->setByExternal === false) { + if (!$this->memcached->quit()) { + return false; + } + $this->memcached = null; } - $this->memcached = null; return true; } diff --git a/src/SaveHandlers/RedisHandler.php b/src/SaveHandlers/RedisHandler.php index d0ebed8..8ac9beb 100644 --- a/src/SaveHandlers/RedisHandler.php +++ b/src/SaveHandlers/RedisHandler.php @@ -80,6 +80,7 @@ protected function prepareConfig(#[SensitiveParameter] array $config) : void public function setRedis(Redis $redis) : static { + $this->setByExternal = true; $this->redis = $redis; return $this; } @@ -192,19 +193,21 @@ public function close() : bool if (!isset($this->redis)) { return true; } - try { - if ($this->redis->ping()) { - if ($this->lockId) { - $this->redis->del($this->lockId); - } - if (!$this->redis->close()) { - return false; + if ($this->setByExternal === false) { + try { + if ($this->redis->ping()) { + if ($this->lockId) { + $this->redis->del($this->lockId); + } + if (!$this->redis->close()) { + return false; + } } + } catch (RedisException $e) { + $this->log('Session (redis): Got RedisException on close: ' . $e->getMessage()); } - } catch (RedisException $e) { - $this->log('Session (redis): Got RedisException on close: ' . $e->getMessage()); + $this->redis = null; } - $this->redis = null; return true; } diff --git a/tests/SaveHandlers/DatabaseHandlerTest.php b/tests/SaveHandlers/DatabaseHandlerTest.php index b18e2e6..9deaba9 100644 --- a/tests/SaveHandlers/DatabaseHandlerTest.php +++ b/tests/SaveHandlers/DatabaseHandlerTest.php @@ -188,5 +188,7 @@ public function testDatabaseSetterAndGetter() : void $handler->setDatabase($database); self::assertTrue($handler->open('', '')); self::assertSame($database, $handler->getDatabase()); + self::assertTrue($handler->close()); + self::assertSame($database, $handler->getDatabase()); } } diff --git a/tests/SaveHandlers/MemcachedHandlerTest.php b/tests/SaveHandlers/MemcachedHandlerTest.php index 7d41ad1..7669821 100644 --- a/tests/SaveHandlers/MemcachedHandlerTest.php +++ b/tests/SaveHandlers/MemcachedHandlerTest.php @@ -190,5 +190,7 @@ public function testMemcachedSetterAndGetter() : void $handler->setMemcached($memcached); self::assertTrue($handler->open('', '')); self::assertSame($memcached, $handler->getMemcached()); + self::assertTrue($handler->close()); + self::assertSame($memcached, $handler->getMemcached()); } } diff --git a/tests/SaveHandlers/RedisHandlerTest.php b/tests/SaveHandlers/RedisHandlerTest.php index 0122bd7..b8eec6e 100644 --- a/tests/SaveHandlers/RedisHandlerTest.php +++ b/tests/SaveHandlers/RedisHandlerTest.php @@ -145,5 +145,7 @@ public function testRedisSetterAndGetter() : void $handler->setRedis($redis); self::assertTrue($handler->open('', '')); self::assertSame($redis, $handler->getRedis()); + self::assertTrue($handler->close()); + self::assertSame($redis, $handler->getRedis()); } }