Sessionen
HTTP ist ein zustandsloses Protokoll, aber fast jede Anwendung muss zwischen den Anfragen einen Zustand beibehalten, z. B. den Inhalt eines Warenkorbs. Hierfür wird eine Session verwendet. Schauen wir mal
- wie man Sessions verwendet
- wie man Benennungskonflikte vermeiden kann
- wie man eine Ablaufzeit festlegt
Bei der Verwendung von Sessionen erhält jeder Benutzer eine eindeutige Kennung, die sogenannte Sessions-ID, die in einem Cookie übergeben wird. Dieser dient als Schlüssel zu den Sessionsdaten. Im Gegensatz zu Cookies, die auf der Browserseite gespeichert werden, werden Sessionsdaten auf der Serverseite gespeichert.
Wir konfigurieren die Session in der Konfiguration, die Wahl der Ablaufzeit ist wichtig.
Die Session wird durch das Nette\Http\Session Objekt
verwaltet, das Sie durch Übergabe mittels Dependency Injection
erhalten. In Presentern rufen Sie einfach $session = $this->getSession()
auf.
→ Installation und Anforderungen
Session starten
Standardmäßig startet Nette eine Session automatisch, sobald wir beginnen, Daten aus ihr zu lesen oder in sie zu schreiben.
Um eine Session manuell zu starten, verwenden Sie $session->start()
.
PHP sendet beim Starten der Session HTTP-Header, die die Zwischenspeicherung beeinflussen, siehe session_cache_limiter, und möglicherweise ein Cookie mit der Sessions-ID. Daher ist es immer notwendig, die Session zu starten, bevor irgendeine Ausgabe an den Browser gesendet wird, da sonst eine Ausnahme ausgelöst wird. Wenn Sie also wissen, dass eine Session während des Renderns der Seite verwendet wird, starten Sie sie vorher manuell, zum Beispiel im Präsentator.
Im Entwicklermodus startet Tracy die Session, weil es sie zur Anzeige von Umleitungs- und AJAX-Anforderungsleisten in der Tracy-Leiste verwendet.
Abschnitt
In reinem PHP ist der Sessionsdatenspeicher als Array implementiert, das über eine globale Variable $_SESSION
zugänglich ist. Das Problem ist, dass Anwendungen normalerweise aus einer Reihe unabhängiger Teile bestehen, und wenn alle nur
ein einziges Array zur Verfügung haben, kommt es früher oder später zu einer Namenskollision.
Nette Framework löst das Problem, indem es den gesamten Raum in Abschnitte (Objekte Nette\Http\SessionSection) unterteilt. Jede Einheit verwendet dann ihren eigenen Abschnitt mit einem eindeutigen Namen, so dass keine Kollisionen auftreten können.
Wir erhalten den Abschnitt vom Sessionsmanager:
$section = $session->getSection('unique name');
Im Präsentator genügt es, getSession()
mit dem Parameter aufzurufen:
// $this ist Presenter
$section = $this->getSession('eindeutiger Name');
Das Vorhandensein des Abschnitts kann mit der Methode $session->hasSection('unique name')
überprüft
werden.
Der Abschnitt selbst ist mit den Methoden set()
, get()
und remove()
sehr einfach zu
bearbeiten:
// Schreiben von Variablen
$section->set('benutzername', 'franta');
// Lesen einer Variable, gibt null zurück, wenn sie nicht existiert
echo $section->get('benutzername');
// Entfernen von Variablen
$section->remove('benutzername');
Es ist möglich, den Zyklus foreach
zu verwenden, um alle Variablen von section zu erhalten:
foreach ($section as $key => $val) {
echo "$key = $val";
}
Wie man den Verfall einstellt
Die Gültigkeitsdauer kann für einzelne Bereiche oder sogar einzelne Variablen festgelegt werden. Wir können die Anmeldung des Benutzers in 20 Minuten ablaufen lassen, aber den Inhalt eines Warenkorbs trotzdem speichern.
// Der Abschnitt läuft nach 20 Minuten ab
$section->setExpiration('20 minutes');
Der dritte Parameter der Methode set()
wird verwendet, um das Verfallsdatum für einzelne Variablen
festzulegen:
// Die Variable "flash" läuft nach 30 Sekunden ab
$section->set('flash', $message, '30 seconds');
Beachten Sie, dass die Verfallszeit der gesamten Session (siehe Sessionskonfiguration) gleich oder höher sein muss als die für einzelne Abschnitte oder Variablen eingestellte Zeit.
Die Aufhebung des zuvor eingestellten Verfalls kann mit der Methode removeExpiration()
erreicht werden. Die
sofortige Löschung des gesamten Abschnitts wird durch die Methode remove()
gewährleistet.
Ereignisse $onStart, $onBeforeWrite
Das Objekt Nette\Http\Session
hat die Ereignisse
$onStart
und $onBeforeWrite
, so dass Sie Rückrufe hinzufügen können, die nach dem Start der Session
oder vor dem Schreiben auf die Festplatte und dem anschließenden Beenden der Session aufgerufen werden.
$session->onBeforeWrite[] = function () {
// Daten in die Session schreiben
$this->section->set('basket', $this->basket);
};
Sessionsverwaltung
Überblick über die Methoden der Klasse Nette\Http\Session
zur Sessionsverwaltung:
start(): void
Startet eine Session.
isStarted(): bool
Ist die Session gestartet?
close(): void
Beendet die Session. Die Session wird automatisch am Ende des Skripts beendet.
destroy(): void
Beendet und löscht die Session.
exists(): bool
Enthält die HTTP-Anfrage ein Cookie mit einer Sessions-ID?
regenerateId(): void
Erzeugt eine neue zufällige Sessions-ID. Die Daten bleiben unverändert.
getId(): string
Gibt die Sessions-ID zurück.
Konfiguration
Wir konfigurieren die Session in der Konfiguration. Wenn Sie eine Anwendung schreiben, die keinen DI-Container verwendet, verwenden Sie diese Methoden, um sie zu konfigurieren. Sie müssen vor dem Start der Session aufgerufen werden.
setName(string $name): static
Legt den Namen des Cookies fest, der zur Übertragung der Sessions-ID verwendet wird. Der Standardname ist
PHPSESSID
. Dies ist nützlich, wenn Sie mehrere verschiedene Anwendungen auf derselben Website ausführen.
getName(): string
Gibt den Namen des Session-Cookies zurück.
setOptions(array $options): static
Konfiguriert die Session. Es ist möglich, alle PHP-Session-Direktiven zu setzen (im camelCase-Format, z.B.
savePath
statt session.save_path
zu schreiben) und auch readAndClose.
setExpiration(?string $time): static
Legt die Zeit der Inaktivität fest, nach der die Session abläuft.
setCookieParameters(string $path, ?string $domain=null, ?bool $secure=null, ?string $samesite=null): static
Legt Parameter für Cookies fest. Sie können die Standardparameterwerte in configuration ändern.
setSavePath(string $path): static
Legt das Verzeichnis fest, in dem Sessionsdateien gespeichert werden.
setHandler(\SessionHandlerInterface $handler): static
Legt einen eigenen Handler fest, siehe PHP-Dokumentation.
Sicherheit zuerst
Der Server geht davon aus, dass er mit demselben Benutzer kommuniziert, solange die Anfragen dieselbe Sessionskennung enthalten. Die Aufgabe von Sicherheitsmechanismen ist es, sicherzustellen, dass dieses Verhalten auch wirklich funktioniert und dass es keine Möglichkeit gibt, eine Kennung zu ersetzen oder zu stehlen.
Aus diesem Grund konfiguriert Nette Framework die PHP-Direktiven so, dass die Sessions-ID nur in Cookies übertragen wird, der Zugriff von JavaScript vermieden wird und die Identifikatoren in der URL ignoriert werden. Außerdem wird in kritischen Momenten, z. B. bei der Anmeldung eines Benutzers, eine neue Sessions-ID generiert.
Die Funktion ini_set wird für die Konfiguration von PHP verwendet, aber leider ist ihre Verwendung bei einigen Webhosting-Diensten verboten. Wenn dies bei Ihnen der Fall ist, versuchen Sie, Ihren Hosting-Anbieter zu bitten, diese Funktion für Sie zuzulassen oder zumindest seinen Server richtig zu konfigurieren.