Nette Documentation Preview

syntax
Sessionen
*********

<div class=perex>

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

</div>

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 |configuration#session], die Wahl der Ablaufzeit ist wichtig.

Die Session wird durch das [api:Nette\Http\Session] Objekt verwaltet, das Sie durch Übergabe mittels [Dependency Injection |dependency-injection:passing-dependencies] erhalten. In Presentern rufen Sie einfach `$session = $this->getSession()` auf.

→ [Installation und Anforderungen |@home#Installation]


Session starten .[#toc-starting-session]
========================================

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 [php: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 .[#toc-section]
=========================

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 [api: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:

```php
$section = $session->getSection('unique name');
```

Im Präsentator genügt es, `getSession()` mit dem Parameter aufzurufen:

```php
// $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:

```php
// 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:

```php
foreach ($section as $key => $val) {
	echo "$key = $val";
}
```


Wie man den Verfall einstellt .[#toc-how-to-set-expiration]
-----------------------------------------------------------

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.

```php
// 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:

```php
// Die Variable "flash" läuft nach 30 Sekunden ab
$section->set('flash', $message, '30 seconds');
```

.[note]
Beachten Sie, dass die Verfallszeit der gesamten Session (siehe [Sessionskonfiguration |configuration#session]) 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 .[#toc-events-onstart-onbeforewrite]
------------------------------------------------------------------------

Das Objekt `Nette\Http\Session` hat die [Ereignisse |nette:glossary#Events] `$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.

```php
$session->onBeforeWrite[] = function () {
	// Daten in die Session schreiben
	$this->section->set('basket', $this->basket);
};
```


Sessionsverwaltung .[#toc-session-management]
=============================================

Überblick über die Methoden der Klasse `Nette\Http\Session` zur Sessionsverwaltung:

<div class=wiki-methods-brief>


start(): void .[method]
-----------------------
Startet eine Session.


isStarted(): bool .[method]
---------------------------
Ist die Session gestartet?


close(): void .[method]
-----------------------
Beendet die Session. Die Session wird automatisch am Ende des Skripts beendet.


destroy(): void .[method]
-------------------------
Beendet und löscht die Session.


exists(): bool .[method]
------------------------
Enthält die HTTP-Anfrage ein Cookie mit einer Sessions-ID?


regenerateId(): void .[method]
------------------------------
Erzeugt eine neue zufällige Sessions-ID. Die Daten bleiben unverändert.


getId(): string .[method]
-------------------------
Gibt die Sessions-ID zurück.

</div>


Konfiguration .[#toc-configuration]
-----------------------------------

Wir konfigurieren die Session in der [Konfiguration |configuration#session]. 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.

<div class=wiki-methods-brief>


setName(string $name): static .[method]
---------------------------------------
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 .[method]
---------------------------
Gibt den Namen des Session-Cookies zurück.


setOptions(array $options): static .[method]
--------------------------------------------
Konfiguriert die Session. Es ist möglich, alle [PHP-Session-Direktiven |https://www.php.net/manual/en/session.configuration.php] zu setzen (im camelCase-Format, z.B. `savePath` statt `session.save_path` zu schreiben) und auch [readAndClose |https://www.php.net/manual/en/function.session-start.php#refsect1-function.session-start-parameters].


setExpiration(?string $time): static .[method]
----------------------------------------------
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 .[method]
---------------------------------------------------------------------------------------------------------------------
Legt Parameter für Cookies fest. Sie können die Standardparameterwerte in [configuration |configuration#Session cookie] ändern.


setSavePath(string $path): static .[method]
-------------------------------------------
Legt das Verzeichnis fest, in dem Sessionsdateien gespeichert werden.


setHandler(\SessionHandlerInterface $handler): static .[method]
---------------------------------------------------------------
Legt einen eigenen Handler fest, siehe [PHP-Dokumentation |https://www.php.net/manual/en/class.sessionhandlerinterface.php].

</div>


Sicherheit zuerst .[#toc-safety-first]
======================================

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. .[note]

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.