Sessions
HTTP ist ein zustandsloses Protokoll, jedoch muss fast jede Anwendung den Zustand zwischen Anfragen aufrechterhalten, beispielsweise den Inhalt eines Warenkorbs. Genau dafür dienen Sessions oder Sitzungen. Wir zeigen Ihnen,
- wie man Sessions verwendet
- wie man Namenskonflikte vermeidet
- wie man die Ablaufzeit einstellt
Bei der Verwendung von Sessions erhält jeder Benutzer eine eindeutige Kennung, die sogenannte Session-ID, die in einem Cookie übermittelt wird. Diese dient als Schlüssel zu den Session-Daten. Im Gegensatz zu Cookies, die auf der Browserseite gespeichert werden, werden die Daten in der Session auf der Serverseite gespeichert.
Die Session wird in der Konfiguration eingestellt, wichtig ist insbesondere die Wahl der Ablaufzeit.
Die Verwaltung der Session übernimmt das Objekt Nette\Http\Session, auf das Sie zugreifen können, indem Sie
es sich mittels Dependency Injection übergeben
lassen. In Presentern reicht es aus, $session = $this->getSession()
aufzurufen.
→ Installation und Anforderungen
Session starten
Nette startet die Session standardmäßig automatisch in dem Moment, in dem wir beginnen, Daten daraus zu lesen oder
hineinzuschreiben. Manuell wird die Session mit $session->start()
gestartet.
PHP sendet beim Starten der Session HTTP-Header, die das Caching beeinflussen, siehe session_cache_limiter, und gegebenenfalls auch ein Cookie mit der Session-ID. Daher ist es notwendig, die Session immer zu starten, bevor irgendeine Ausgabe an den Browser gesendet wird, andernfalls wird eine Ausnahme ausgelöst. Wenn Sie also wissen, dass während des Renderns der Seite die Session verwendet wird, starten Sie sie manuell vorher, zum Beispiel im Presenter.
Im Entwicklermodus startet Tracy die Session, da sie diese zur Anzeige von Balken mit Weiterleitungen und AJAX-Anfragen in der Tracy Bar verwendet.
Abschnitte
In reinem PHP wird der Datenspeicher der Session als Array realisiert, das über die globale Variable $_SESSION
zugänglich ist. Das Problem dabei ist, dass Anwendungen üblicherweise aus einer Reihe voneinander unabhängiger Teile bestehen,
und wenn alle nur ein Array zur Verfügung haben, kommt es früher oder später zu Namenskollisionen.
Das Nette Framework löst dieses Problem, indem es den gesamten Raum in Abschnitte (Objekte Nette\Http\SessionSection) unterteilt. Jede Einheit verwendet dann ihren eigenen Abschnitt mit einem eindeutigen Namen, und es kann zu keiner Kollision mehr kommen.
Einen Abschnitt erhalten wir aus der Session:
$section = $session->getSection('eindeutigerName');
Im Presenter genügt es, getSession()
mit einem Parameter zu verwenden:
// $this ist Presenter
$section = $this->getSession('eindeutigerName');
Die Existenz eines Abschnitts kann mit der Methode $session->hasSection('eindeutigerName')
überprüft
werden.
Mit dem Abschnitt selbst arbeitet man dann sehr einfach mithilfe der Methoden set()
, get()
und
remove()
:
// Variable schreiben
$section->set('userName', 'franta');
// Variable lesen, gibt null zurück, wenn sie nicht existiert
echo $section->get('userName');
// Variable löschen
$section->remove('userName');
Um alle Variablen aus einem Abschnitt zu erhalten, kann eine foreach
-Schleife verwendet werden:
foreach ($section as $key => $val) {
echo "$key = $val";
}
Ablaufzeit einstellen
Für einzelne Abschnitte oder sogar einzelne Variablen kann eine Ablaufzeit eingestellt werden. So können wir die Anmeldung eines Benutzers nach 20 Minuten ablaufen lassen, aber den Inhalt des Warenkorbs weiterhin speichern.
// Abschnitt läuft nach 20 Minuten ab
$section->setExpiration('20 minutes');
Zur Einstellung der Ablaufzeit einzelner Variablen dient der dritte Parameter der Methode set()
:
// Variable 'flash' läuft bereits nach 30 Sekunden ab
$section->set('flash', $message, '30 seconds');
Vergessen Sie nicht, dass die Ablaufzeit der gesamten Session (siehe Session-Konfiguration) gleich oder länger sein muss als die bei einzelnen Abschnitten oder Variablen eingestellte Zeit.
Das Löschen einer zuvor eingestellten Ablaufzeit erreichen wir mit der Methode removeExpiration()
. Das sofortige
Löschen des gesamten Abschnitts stellt die Methode remove()
sicher.
Ereignisse $onStart, $onBeforeWrite
Das Objekt Nette\Http\Session
hat die Ereignisse
$onStart
und $onBeforeWrite
, Sie können also Callbacks hinzufügen, die nach dem Start der Session oder
vor ihrem Schreiben auf die Festplatte und dem anschließenden Beenden aufgerufen werden.
$session->onBeforeWrite[] = function () {
// Wir schreiben Daten in die Session
$this->section->set('basket', $this->basket);
};
Session-Verwaltung
Übersicht der Methoden der Klasse Nette\Http\Session
zur Session-Verwaltung:
start(): void
Startet die Session.
isStarted(): bool
Ist die Session gestartet?
close(): void
Beendet die Session. Die Session wird automatisch am Ende des Skriptlaufs beendet.
destroy(): void
Beendet und löscht die Session.
exists(): bool
Enthält die HTTP-Anfrage ein Cookie mit einer Session-ID?
regenerateId(): void
Generiert eine neue zufällige Session-ID. Die Daten bleiben erhalten.
getId(): string
Gibt die Session-ID zurück.
Konfiguration
Die Session wird in der Konfiguration eingestellt. Wenn Sie eine Anwendung schreiben, die keinen DI-Container verwendet, dienen diese Methoden zur Konfiguration. Sie müssen aufgerufen werden, bevor die Session gestartet wird.
setName (string $name): static
Legt den Namen des Cookies fest, in dem die Session-ID übertragen wird. Der Standardname ist PHPSESSID
. Dies ist
nützlich, wenn Sie mehrere unterschiedliche Anwendungen innerhalb einer Website betreiben.
getName(): string
Gibt den Namen des Cookies zurück, in dem die Session-ID übertragen wird.
setOptions (array $options): static
Konfiguriert die Session. Es können alle PHP Session-Direktiven (im CamelCase-Format, z.B. statt
session.save_path
schreiben wir savePath
) sowie readAndClose
eingestellt werden.
setExpiration (?string $time): static
Legt die Inaktivitätsdauer fest, nach der die Session abläuft.
setCookieParameters (string $path, ?string $domain=null, ?bool $secure=null, ?string $samesite=null): static
Einstellung der Parameter für das Cookie. Die Standardwerte der Parameter können Sie in der Konfiguration ändern.
setSavePath (string $path): static
Legt das Verzeichnis fest, in dem die Session-Dateien gespeichert werden.
setHandler (\SessionHandlerInterface $handler): static
Einstellung eines eigenen Handlers, siehe PHP-Dokumentation.
Sicherheit geht vor
Der Server geht davon aus, dass er immer mit demselben Benutzer kommuniziert, solange die Anfragen von derselben Session-ID begleitet werden. Die Aufgabe der Sicherheitsmechanismen besteht darin, sicherzustellen, dass dies tatsächlich der Fall ist und es nicht möglich ist, die Kennung zu stehlen oder unterzuschieben.
Das Nette Framework konfiguriert daher die PHP-Direktiven korrekt, um die Session-ID nur im Cookie zu übertragen, sie für JavaScript unzugänglich zu machen und eventuelle Kennungen in der URL zu ignorieren. Darüber hinaus generiert es in kritischen Momenten, wie z. B. bei der Benutzeranmeldung, eine neue Session-ID.
Zur Konfiguration von PHP wird die Funktion ini_set verwendet, die leider von einigen Hostern verboten wird. Wenn dies auch bei Ihrem Hoster der Fall ist, versuchen Sie, mit ihm zu vereinbaren, dass er Ihnen die Funktion erlaubt oder zumindest den Server konfiguriert.