179 lines
3.6 KiB
PHP
179 lines
3.6 KiB
PHP
<?php
|
|
|
|
/**
|
|
* Session provides session management with flash messages and CSRF protection
|
|
*/
|
|
class Session
|
|
{
|
|
private bool $started = false;
|
|
private array $flashData = [];
|
|
|
|
/**
|
|
* start initializes the session if not already started
|
|
*/
|
|
public function start(): void
|
|
{
|
|
if ($this->started || session_status() === PHP_SESSION_ACTIVE) {
|
|
$this->started = true;
|
|
$this->loadFlashData();
|
|
return;
|
|
}
|
|
|
|
session_start();
|
|
$this->started = true;
|
|
$this->loadFlashData();
|
|
}
|
|
|
|
/**
|
|
* get retrieves a value from the session
|
|
*/
|
|
public function get(string $key, mixed $default = null): mixed
|
|
{
|
|
$this->ensureStarted();
|
|
return $_SESSION[$key] ?? $default;
|
|
}
|
|
|
|
/**
|
|
* set stores a value in the session
|
|
*/
|
|
public function set(string $key, mixed $value): void
|
|
{
|
|
$this->ensureStarted();
|
|
$_SESSION[$key] = $value;
|
|
}
|
|
|
|
/**
|
|
* has checks if a key exists in the session
|
|
*/
|
|
public function has(string $key): bool
|
|
{
|
|
$this->ensureStarted();
|
|
return isset($_SESSION[$key]);
|
|
}
|
|
|
|
/**
|
|
* remove deletes a value from the session
|
|
*/
|
|
public function remove(string $key): void
|
|
{
|
|
$this->ensureStarted();
|
|
unset($_SESSION[$key]);
|
|
}
|
|
|
|
/**
|
|
* flash sets a flash message that will be available only for the next request
|
|
*/
|
|
public function flash(string $key, mixed $value): void
|
|
{
|
|
$this->ensureStarted();
|
|
$_SESSION['_flash_new'][$key] = $value;
|
|
}
|
|
|
|
/**
|
|
* getFlash retrieves a flash message (available only for current request)
|
|
*/
|
|
public function getFlash(string $key, mixed $default = null): mixed
|
|
{
|
|
return $this->flashData[$key] ?? $default;
|
|
}
|
|
|
|
/**
|
|
* hasFlash checks if a flash message exists
|
|
*/
|
|
public function hasFlash(string $key): bool
|
|
{
|
|
return isset($this->flashData[$key]);
|
|
}
|
|
|
|
/**
|
|
* csrfToken generates or retrieves the CSRF token for the session
|
|
*/
|
|
public function csrfToken(): string
|
|
{
|
|
$this->ensureStarted();
|
|
if (!isset($_SESSION['_csrf_token'])) $_SESSION['_csrf_token'] = bin2hex(random_bytes(32));
|
|
return $_SESSION['_csrf_token'];
|
|
}
|
|
|
|
/**
|
|
* validateCsrf validates a CSRF token
|
|
*/
|
|
public function validateCsrf(string $token): bool
|
|
{
|
|
$this->ensureStarted();
|
|
if (!isset($_SESSION['_csrf_token'])) return false;
|
|
return hash_equals($_SESSION['_csrf_token'], $token);
|
|
}
|
|
|
|
/**
|
|
* regenerate regenerates the session ID for security
|
|
*/
|
|
public function regenerate(bool $deleteOldSession = true): bool
|
|
{
|
|
$this->ensureStarted();
|
|
return session_regenerate_id($deleteOldSession);
|
|
}
|
|
|
|
/**
|
|
* destroy destroys the session
|
|
*/
|
|
public function destroy(): void
|
|
{
|
|
$this->ensureStarted();
|
|
|
|
$_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();
|
|
$this->started = false;
|
|
$this->flashData = [];
|
|
}
|
|
|
|
/**
|
|
* clear removes all session data but keeps the session active
|
|
*/
|
|
public function clear(): void
|
|
{
|
|
$this->ensureStarted();
|
|
$_SESSION = [];
|
|
$this->flashData = [];
|
|
}
|
|
|
|
/**
|
|
* all returns all session data
|
|
*/
|
|
public function all(): array
|
|
{
|
|
$this->ensureStarted();
|
|
$data = $_SESSION;
|
|
unset($data['_flash_old'], $data['_flash_new'], $data['_csrf_token']);
|
|
return $data;
|
|
}
|
|
|
|
/**
|
|
* ensureStarted ensures the session is started
|
|
*/
|
|
private function ensureStarted(): void
|
|
{
|
|
if (!$this->started) $this->start();
|
|
}
|
|
|
|
/**
|
|
* loadFlashData loads flash messages and rotates them
|
|
*/
|
|
private function loadFlashData(): void
|
|
{
|
|
$this->flashData = $_SESSION['_flash_old'] ?? [];
|
|
|
|
$_SESSION['_flash_old'] = $_SESSION['_flash_new'] ?? [];
|
|
unset($_SESSION['_flash_new']);
|
|
}
|
|
}
|