true, 'cookie_secure' => false, // Set to true if HTTPS is enforced (e.g. on production) 'cookie_samesite' => 'Lax', ]); } // Mark existing flash messages to be deleted next request $this->ageFlashMessages(); } /** * Set a session value. */ public function set(string $key, mixed $value): void { $_SESSION[$key] = $value; } /** * Get a session value. */ public function get(string $key, mixed $default = null): mixed { return $_SESSION[$key] ?? $default; } /** * Remove a session value. */ public function remove(string $key): void { unset($_SESSION[$key]); } /** * Check if a session key exists. */ public function has(string $key): bool { return isset($_SESSION[$key]); } /** * Set a flash message (available only for the next request). */ public function setFlash(string $key, string $message): void { $_SESSION[self::FLASH_KEY][$key] = [ 'value' => $message, 'remove' => false ]; } /** * Get a flash message. */ public function getFlash(string $key, ?string $default = null): ?string { return $_SESSION[self::FLASH_KEY][$key]['value'] ?? $default; } /** * Get all flash messages. */ public function getFlashes(): array { $flashes = []; foreach ($_SESSION[self::FLASH_KEY] ?? [] as $key => $flash) { $flashes[$key] = $flash['value']; } return $flashes; } /** * Age flash messages at start of request. */ private function ageFlashMessages(): void { $flashMessages = $_SESSION[self::FLASH_KEY] ?? []; foreach ($flashMessages as $key => &$flash) { if ($flash['remove']) { unset($flashMessages[$key]); } else { $flash['remove'] = true; } } $_SESSION[self::FLASH_KEY] = $flashMessages; } /** * Generate or fetch CSRF token. */ public function getCsrfToken(): string { $token = $this->get('csrf_token'); if (!$token) { $token = bin2hex(random_bytes(32)); $this->set('csrf_token', $token); } return $token; } /** * Validate CSRF token. */ public function validateCsrfToken(?string $token): bool { if (!$token) { return false; } $storedToken = $this->get('csrf_token'); return hash_equals($storedToken, $token); } /** * Destroy the session. */ public function destroy(): void { $_SESSION = []; if (ini_get("session.use_cookies")) { $params = session_get_cookie_params(); setcookie( session_name(), '', time() - 42000, $params["path"], $params["domain"], $params["secure"], $params["httponly"] ); } session_destroy(); } }