Skip to content
Closed
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

- Enh #86: Remove `yiisoft/cookies` dependency (@vjik)
- Bug #86: `NullSession::getCookieParameters()` now returns proper cookie parameters instead of an empty array (@vjik)
- Bug #88: Fix reusing the previous session ID in `Session::open()` in long-running workers (@klsoft-web)

## 3.0.2 August 26, 2026

Expand Down
22 changes: 18 additions & 4 deletions src/Session.php
Original file line number Diff line number Diff line change
Expand Up @@ -84,17 +84,15 @@ public function close(): void
}

/**
* @throw SessionException When start session is failed.
* @throws SessionException When start session is failed.
*/
public function open(): void
{
if ($this->isActive()) {
return;
}

if ($this->sessionId !== null) {
session_id($this->sessionId);
}
session_id($this->sessionId ?? $this->createId());

try {
session_start($this->options);
Expand Down Expand Up @@ -220,4 +218,20 @@ public function setId(string $sessionId): void
{
$this->sessionId = $sessionId;
}

/**
* @throws SessionException When create session id is failed.
*/
private function createId(): string
{
$sessionId = session_create_id();
/** @psalm-suppress TypeDoesNotContainType PHP 8.0 stub in Psalm lacks `false` in the return type. */
if ($sessionId === false) {
// @codeCoverageIgnoreStart
throw new SessionException('Failed to create ID.');
// @codeCoverageIgnoreEnd
}

return $sessionId;
}
}
13 changes: 13 additions & 0 deletions tests/SessionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,19 @@ public function testRegenerateIdOpensInactiveSession(): void
self::assertNotEquals($id, $session->getId());
}

public function testOpenDoesNotReuseIdOfClosedSession(): void
{
$firstSession = new Session();
$firstSession->open();
$firstId = $firstSession->getId();
$firstSession->close();

$secondSession = new Session();
$secondSession->open();

self::assertNotSame($firstId, $secondSession->getId());
}

public function testDiscard(): void
{
$session = $this->getSession();
Expand Down
Loading