Auto-gegenereerd via Reflection — blijft altijd in sync met src/.
ArraySessionStore
Framework\Session\ArraySessionStoreIn-memory store — bedoeld voor tests, niet voor productie.
Eén instance per test; sessies overleven niet tussen requests/processes.
7 public methods
count(): intTest-helper: aantal records nu in de store.
delete(string $id): voidgc(int $now): intids(): arrayTest-helper: alle ids in de store.
read(string $id): ?\SessionRecordtouch(string $id, int $lastActivityAt): voidwrite(string $id, \SessionRecord $record): voidFileSessionStore
Framework\Session\FileSessionStoreFile-backed sessie-opslag — één bestand per sessie-id onder een directory.
Bedoeld voor apps zonder DB of voor dev-omgevingen. Voor productie-load met
meerdere webservers heb je een gedeelde store nodig — gebruik dan
{@see PdoSessionStore} of een Redis-implementatie.
$store = new FileSessionStore($appRoot . '/data/sessions');
$session = new Session($store);
Bestandsformaat: JSON-serialized SessionRecord met UNIX-timestamp velden.
Filename = `<id>.session` zodat je per ongeluk niet andere files in dezelfde
dir matcht bij een listing.
__construct(string $directory)5 public methods
delete(string $id): voidgc(int $now): intread(string $id): ?\SessionRecordtouch(string $id, int $lastActivityAt): voidwrite(string $id, \SessionRecord $record): voidFlash
Framework\Session\FlashFlash-berichten — éénmalige meldingen die over één request-grens leven
(typisch: server-side validatie-fout, redirect, volgende GET toont 'em).
$flash->add('success', 'Event opgeslagen');
$flash->add('error', 'Ongeldig formulier');
header('Location: /events'); exit;
// Volgende request:
foreach ($flash->all() as $type => $msgs) { … } // verwijdert direct
// of:
$errors = $flash->get('error'); // verwijdert alleen 'error'
$still = $flash->peek('error'); // niet-consumerend lezen
Storage: array<string, list<string>> onder sessie-key `_flash`.
`get()` en `all()` consumeren de berichten — daarna zijn ze weg uit de
sessie. `peek()` en `has()` zijn niet-consumerend.
Geen HTML-rendering in deze klasse: het type ('success'/'error'/etc.) is een
vrije string die de template gebruikt om kleur/icoon te kiezen.
__construct(\Session $session)5 public methods
add(string $type, string $message): voidall(): arrayget(string $type): arrayhas(string $type): boolpeek(string $type): arrayPdoSessionStore
Framework\Session\PdoSessionStorePDO-backed sessie-opslag bovenop {@see Adapter}.
Vereist een tabel met dit schema (caller is verantwoordelijk voor migraties):
CREATE TABLE sessions (
id CHAR(64) NOT NULL PRIMARY KEY,
payload MEDIUMTEXT NOT NULL,
ip_address VARCHAR(45) NULL,
user_agent VARCHAR(300) NULL,
last_activity INT UNSIGNED NOT NULL,
expires_at INT UNSIGNED NOT NULL,
INDEX idx_sessions_expires (expires_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
Tijden worden bewust als UNIX-timestamps opgeslagen — portable tussen
MySQL/MariaDB/SQLite/Postgres en geen timezone-conversies.
Tabelnaam is configureerbaar maar wordt strikt gevalideerd ([a-zA-Z_][a-zA-Z0-9_]*).
__construct(\Adapter $db, string $table = 'sessions')5 public methods
delete(string $id): voidgc(int $now): intread(string $id): ?\SessionRecordtouch(string $id, int $lastActivityAt): voidwrite(string $id, \SessionRecord $record): voidSession
Framework\Session\SessionCookie + store-backed sessie. Generiek — kent geen "user"-concept; caller
stopt zelf user_id/role/etc. in de payload via `set()`.
$session = new Session(new PdoSessionStore($db));
$session->start();
if (!$session->has('user_id')) {
// login flow:
$session->regenerate(); // fixation-veilig nieuwe id
$session->set('user_id', 42);
}
$userId = $session->get('user_id'); // bij latere requests
$session->destroy(); // logout
Veilig per default:
- 64-hex token (256 bits entropy via random_bytes)
- HttpOnly + Secure + SameSite=Lax cookie
- Versie-invalidatie: bump SessionConfig::$version → bestaande sessies
worden automatisch leeggegooid bij start()
- last_activity wordt geknepen tot 1x per touchThrottleSeconds (default 60s)
- Probabilistic GC (1/gcDivisor requests, default 1/50)
Niet-veilig per default:
- Cookie-write gebeurt via setcookie(); test-injectie via constructor-arg
- REMOTE_ADDR wordt rauw gelezen (geen X-Forwarded-For-fallback) — caller
moet zelf een trusted-proxy laag hebben als die nodig is
__construct(\SessionStoreInterface $store, \SessionConfig $config = \Framework\Session\SessionConfig::__set_state(array(
'cookieName' => 'session',
'lifetimeSeconds' => 28800,
'secure' => true,
'httpOnly' => true,
'sameSite' => 'Lax',
'cookiePath' => '/',
'cookieDomain' => NULL,
'touchThrottleSeconds' => 60,
'gcDivisor' => 50,
'version' => 1,
)), ?Closure $cookieWriter = NULL)11 public methods
all(): arrayclear(): voidWis de payload, behoud het sessie-id.
destroy(): voidVerwijder de sessie volledig (store + cookie).
get(string $key, ?mixed $default = NULL): ?mixedhas(string $key): boolid(): ?stringisStarted(): boolregenerate(bool $deleteOld = true): voidGenereer een nieuw sessie-id, behoud de payload.
Voer dit uit bij privilege-escalatie (login, role-switch) tegen
session-fixation.
remove(string $key): voidset(string $key, ?mixed $value): voidstart(): voidLees de cookie en hydrateer de sessie. Idempotent — een tweede aanroep
binnen hetzelfde request is een no-op.
SessionConfig
Framework\Session\SessionConfigConfiguratie voor {@see Session}. Defaults zijn veilig:
`Secure`, `HttpOnly`, `SameSite=Lax`, 8 uur levensduur.
`version` is een caller-controlled integer: bump bij elke wijziging in
payload-structuur (nieuwe keys, verwijderde keys, andere shape) zodat
bestaande sessies automatisch geïnvalideerd worden i.p.v. te crashen
met `Undefined property` op oude data.
__construct(string $cookieName = 'session', int $lifetimeSeconds = 28800, bool $secure = true, bool $httpOnly = true, string $sameSite = 'Lax', string $cookiePath = '/', ?string $cookieDomain = NULL, int $touchThrottleSeconds = 60, int $gcDivisor = 50, int $version = 1)SessionRecord
Framework\Session\SessionRecordEén regel uit een SessionStore — de geserialiseerde toestand van één sessie.
`lastActivityAt` en `expiresAt` zijn UNIX-timestamps (integer seconden) zodat
de implementatie van de store los staat van DB-specifieke datum-types.
__construct(array $payload, int $lastActivityAt, int $expiresAt, ?string $ipAddress = NULL, ?string $userAgent = NULL)SessionStoreInterface
Framework\Session\SessionStoreInterfaceStorage-contract voor sessies. Implementaties (PdoSessionStore, ArraySessionStore)
houden alleen CRUD bij — de hogere-orde logica (cookie, regeneration,
versie-invalidatie, throttling) zit in {@see Session}.
5 public methods
delete(string $id): voidVerwijder één sessie. Idempotent: stilzwijgend als afwezig.
gc(int $now): intVerwijder verlopen sessies (expires_at <= $now).
read(string $id): ?\SessionRecordLees een sessie. Null als afwezig of verlopen.
touch(string $id, int $lastActivityAt): voidWerk last_activity bij zonder de rest van de rij aan te raken.
write(string $id, \SessionRecord $record): voidSchrijf (insert of replace) een sessie.