Store PHP sessions in the `sessions` MySQL table (30-day TTL) instead of server files, which disappear on container restart / redeploy. Cookie lifetime also extended to 30 days. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
39 lines
1.2 KiB
PHP
39 lines
1.2 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
|
|
class DbSessionHandler implements SessionHandlerInterface
|
|
{
|
|
private const TTL = 86400 * 30; // 30 days
|
|
|
|
public function open(string $path, string $name): bool { return true; }
|
|
public function close(): bool { return true; }
|
|
|
|
public function read(string $id): string|false
|
|
{
|
|
$stmt = db()->prepare("SELECT data FROM sessions WHERE id = ? AND updated_at > DATE_SUB(NOW(), INTERVAL " . self::TTL . " SECOND)");
|
|
$stmt->execute([$id]);
|
|
$row = $stmt->fetch();
|
|
return $row ? $row['data'] : '';
|
|
}
|
|
|
|
public function write(string $id, string $data): bool
|
|
{
|
|
db()->prepare("INSERT INTO sessions (id, data) VALUES (?, ?) ON DUPLICATE KEY UPDATE data = VALUES(data), updated_at = NOW()")
|
|
->execute([$id, $data]);
|
|
return true;
|
|
}
|
|
|
|
public function destroy(string $id): bool
|
|
{
|
|
db()->prepare("DELETE FROM sessions WHERE id = ?")->execute([$id]);
|
|
return true;
|
|
}
|
|
|
|
public function gc(int $max_lifetime): int|false
|
|
{
|
|
$stmt = db()->prepare("DELETE FROM sessions WHERE updated_at < DATE_SUB(NOW(), INTERVAL ? SECOND)");
|
|
$stmt->execute([self::TTL]);
|
|
return $stmt->rowCount();
|
|
}
|
|
}
|