Nette Documentation Preview

syntax
Ülések
******

<div class=perex>

A HTTP egy állapotmentes protokoll, de szinte minden alkalmazásnak szüksége van állapot megőrzésére a kérések között, pl. egy bevásárlókosár tartalma. Erre szolgál a munkamenet. Lássuk

- hogyan használjuk a munkameneteket
- hogyan kerüljük el a névkonfliktusokat
- hogyan állítsuk be a lejáratot

</div>

Munkamenetek használatakor minden felhasználó kap egy egyedi azonosítót, a munkamenet-azonosítót, amelyet egy cookie-ban adunk át. Ez szolgál a munkamenetadatok kulcsaként. A sütikkel ellentétben, amelyek a böngésző oldalán tárolódnak, a munkamenetadatokat a kiszolgáló oldalán tárolják.

A munkamenetet a [konfigurációban |configuration#session] állítjuk be, fontos a lejárati idő megválasztása.

A munkamenetet a [api:Nette\Http\Session] objektum kezeli, amelyet [függőségi injektálással |dependency-injection:passing-dependencies] átadva kapunk meg. A prezenterekben egyszerűen hívjuk meg a `$session = $this->getSession()`.

→ [Telepítés és követelmények |@home#Installation]


A munkamenet indítása .[#toc-starting-session]
==============================================

Alapértelmezés szerint a Nette automatikusan elindít egy munkamenetet abban a pillanatban, amikor elkezdünk olvasni belőle vagy adatokat írni rá. A munkamenet manuális indításához használja a `$session->start()` parancsot.

A PHP a munkamenet indításakor a gyorsítótárazást befolyásoló HTTP fejléceket küld, lásd [php:session_cache_limiter], és esetleg egy cookie-t a munkamenet azonosítójával. Ezért mindig el kell indítani a munkamenetet, mielőtt bármilyen kimenetet küldenénk a böngészőnek, különben kivételt dob. Ha tehát tudja, hogy az oldal megjelenítése során munkamenetet fog használni, indítsa el azt manuálisan előtte, például a prezenterben.

Fejlesztői módban a Tracy elindítja a munkamenetet, mert azt használja az átirányítás és az AJAX-kérések sávjainak megjelenítéséhez a Tracy Barban.


A  szakasz. .[#toc-section]
===========================

Tiszta PHP-ben a munkamenet-adattároló egy tömbként van implementálva, amely egy globális változóval érhető el: `$_SESSION`. A probléma az, hogy az alkalmazások általában több független részből állnak, és ha mindegyiknek csak egyazon tömb áll rendelkezésre, előbb-utóbb névütközés következik be.

A Nette Framework úgy oldja meg a problémát, hogy a teljes teret részekre (objektumokra [api:Nette\Http\SessionSection]) osztja. Ilyenkor minden egység a saját szekcióját használja egyedi névvel, és nem fordulhat elő ütközés.

A szekciót a munkamenetkezelőtől kapjuk:

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

A prezenterben elég a `getSession()` paraméterrel meghívni:

```php
// $this a bemutató
$section = $this->getSession('unique name');
```

A szakasz meglétét a `$session->hasSection('unique name')` metódussal lehet ellenőrizni.

Magával a szakasszal nagyon egyszerűen lehet dolgozni a `set()`, `get()` és `remove()` metódusok segítségével:

```php
// változó írása
$section->set('userName', 'franta');

// változó kiolvasása, nullát ad vissza, ha nem létezik
echo $section->get('userName');

// változó eltávolítása
$section->remove('userName');
```

A `foreach` ciklussal a szakasz összes változóját megkaphatjuk:

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


Hogyan állítsuk be a lejáratot .[#toc-how-to-set-expiration]
------------------------------------------------------------

A lejárat beállítható egyes szakaszokhoz vagy akár egyes változókhoz is. Engedhetjük, hogy a felhasználó bejelentkezése 20 perc múlva lejárjon, de a bevásárlókosár tartalmára továbbra is emlékezhetünk.

```php
// a szakasz 20 perc múlva lejár
$section->setExpiration('20 minutes');
```

A `set()` metódus harmadik paramétere az egyes változók lejáratának beállítására szolgál:

```php
// a 'flash' változó 30 másodperc múlva jár le
$section->set('flash', $message, '30 seconds');
```

.[note]
Ne feledje, hogy a teljes munkamenet lejárati idejének (lásd a [munkamenet konfigurációját |configuration#session]) egyenlőnek vagy magasabbnak kell lennie, mint az egyes szakaszokhoz vagy változókhoz beállított idő.

A korábban beállított lejárati idő törlése a `removeExpiration()` módszerrel érhető el. A teljes szakasz azonnali törlését a `remove()` módszer biztosítja.


$onStart, $onBeforeWrite események .[#toc-events-onstart-onbeforewrite]
-----------------------------------------------------------------------

A `Nette\Http\Session` objektum rendelkezik `$onStart` a `$onBeforeWrite`[eseményekkel |nette:glossary#Events], így olyan visszahívásokat adhat hozzá, amelyek a munkamenet elindulása után vagy a munkamenet lemezre írása, majd befejezése előtt hívódnak meg.

```php
$session->onBeforeWrite[] = function () {
	// adatok írása a munkamenetbe
	$this->section->set('basket', $this->basket);
};
```


Munkamenet-kezelés .[#toc-session-management]
=============================================

A `Nette\Http\Session` osztály munkamenet-kezelési metódusainak áttekintése:

<div class=wiki-methods-brief>


start(): void .[method]
-----------------------
Munkamenetet indít.


isStarted(): bool .[method]
---------------------------
Elindult a munkamenet?


close(): void .[method]
-----------------------
A munkamenet befejeződik. A munkamenet automatikusan véget ér a parancsfájl végén.


destroy(): void .[method]
-------------------------
Befejezi és törli a munkamenetet.


exists(): bool .[method]
------------------------
A HTTP-kérelem tartalmaz egy munkamenet-azonosítót tartalmazó sütit?


regenerateId(): void .[method]
------------------------------
Új véletlenszerű munkamenet-azonosítót generál. Az adatok változatlanok maradnak.


getId(): string .[method]
-------------------------
Visszaadja a munkamenet azonosítóját.

</div>


Konfiguráció .[#toc-configuration]
----------------------------------

A [konfigurációban |configuration#session] konfiguráljuk a munkamenetet. Ha olyan alkalmazást írsz, amely nem használ DI konténert, használd ezeket a módszereket a konfiguráláshoz. Ezeket a munkamenet elindítása előtt kell meghívni.

<div class=wiki-methods-brief>


setName(string $name): static .[method]
---------------------------------------
Beállítja a munkamenet azonosítójának továbbítására használt süti nevét. Az alapértelmezett név `PHPSESSID`. Ez akkor hasznos, ha több különböző alkalmazást futtat ugyanazon a webhelyen.


getName(): string .[method]
---------------------------
Visszaadja a munkamenet süti nevét.


setOptions(array $options): static .[method]
--------------------------------------------
A munkamenet konfigurálása. Lehetőség van az összes PHP [munkamenet direktíva |https://www.php.net/manual/en/session.configuration.php] beállítására (camelCase formátumban, pl. `session.save_path` helyett `savePath` írása), valamint [readAndClose |https://www.php.net/manual/en/function.session-start.php#refsect1-function.session-start-parameters].


setExpiration(?string $time): static .[method]
----------------------------------------------
Beállítja az inaktivitás idejét, amely után a munkamenet lejár.


setCookieParameters(string $path, ?string $domain=null, ?bool $secure=null, ?string $samesite=null): static .[method]
---------------------------------------------------------------------------------------------------------------------
A sütik paramétereinek beállítása. Az alapértelmezett paraméterértékeket a [configuration#Session cookie |configuration#Session cookie] menüpontban módosíthatja.


setSavePath(string $path): static .[method]
-------------------------------------------
Beállítja a munkamenetfájlok tárolási könyvtárát.


setHandler(\SessionHandlerInterface $handler): static .[method]
---------------------------------------------------------------
Beállítja az egyéni kezelőt, lásd a [PHP dokumentációt |https://www.php.net/manual/en/class.sessionhandlerinterface.php].

</div>


Első biztonság .[#toc-safety-first]
===================================

A kiszolgáló feltételezi, hogy ugyanazzal a felhasználóval kommunikál, amíg a kérések ugyanazt a munkamenet-azonosítót tartalmazzák. A biztonsági mechanizmusok feladata annak biztosítása, hogy ez a viselkedés valóban működjön, és ne legyen lehetőség az azonosító kicserélésére vagy ellopására.

Ezért a Nette Framework megfelelően konfigurálja a PHP direktívákat, hogy a munkamenet-azonosítót csak sütikben továbbítsa, hogy elkerülje a JavaScriptből való hozzáférést, és hogy figyelmen kívül hagyja az URL-ben szereplő azonosítókat. Sőt, kritikus pillanatokban, például a felhasználó bejelentkezésekor új munkamenet-azonosítót generál.

Az ini_set függvényt a PHP konfigurálására használják, de sajnos egyes webtárhely-szolgáltatóknál tilos a használata. Ha ez a te eseted, próbáld meg kérni a tárhelyszolgáltatódat, hogy engedélyezze neked ezt a funkciót, vagy legalábbis megfelelően konfigurálja a szerverét. .[note]

Ülések

A HTTP egy állapotmentes protokoll, de szinte minden alkalmazásnak szüksége van állapot megőrzésére a kérések között, pl. egy bevásárlókosár tartalma. Erre szolgál a munkamenet. Lássuk

  • hogyan használjuk a munkameneteket
  • hogyan kerüljük el a névkonfliktusokat
  • hogyan állítsuk be a lejáratot

Munkamenetek használatakor minden felhasználó kap egy egyedi azonosítót, a munkamenet-azonosítót, amelyet egy cookie-ban adunk át. Ez szolgál a munkamenetadatok kulcsaként. A sütikkel ellentétben, amelyek a böngésző oldalán tárolódnak, a munkamenetadatokat a kiszolgáló oldalán tárolják.

A munkamenetet a konfigurációban állítjuk be, fontos a lejárati idő megválasztása.

A munkamenetet a Nette\Http\Session objektum kezeli, amelyet függőségi injektálással átadva kapunk meg. A prezenterekben egyszerűen hívjuk meg a $session = $this->getSession().

Telepítés és követelmények

A munkamenet indítása

Alapértelmezés szerint a Nette automatikusan elindít egy munkamenetet abban a pillanatban, amikor elkezdünk olvasni belőle vagy adatokat írni rá. A munkamenet manuális indításához használja a $session->start() parancsot.

A PHP a munkamenet indításakor a gyorsítótárazást befolyásoló HTTP fejléceket küld, lásd session_cache_limiter, és esetleg egy cookie-t a munkamenet azonosítójával. Ezért mindig el kell indítani a munkamenetet, mielőtt bármilyen kimenetet küldenénk a böngészőnek, különben kivételt dob. Ha tehát tudja, hogy az oldal megjelenítése során munkamenetet fog használni, indítsa el azt manuálisan előtte, például a prezenterben.

Fejlesztői módban a Tracy elindítja a munkamenetet, mert azt használja az átirányítás és az AJAX-kérések sávjainak megjelenítéséhez a Tracy Barban.

A szakasz.

Tiszta PHP-ben a munkamenet-adattároló egy tömbként van implementálva, amely egy globális változóval érhető el: $_SESSION. A probléma az, hogy az alkalmazások általában több független részből állnak, és ha mindegyiknek csak egyazon tömb áll rendelkezésre, előbb-utóbb névütközés következik be.

A Nette Framework úgy oldja meg a problémát, hogy a teljes teret részekre (objektumokra Nette\Http\SessionSection) osztja. Ilyenkor minden egység a saját szekcióját használja egyedi névvel, és nem fordulhat elő ütközés.

A szekciót a munkamenetkezelőtől kapjuk:

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

A prezenterben elég a getSession() paraméterrel meghívni:

// $this a bemutató
$section = $this->getSession('unique name');

A szakasz meglétét a $session->hasSection('unique name') metódussal lehet ellenőrizni.

Magával a szakasszal nagyon egyszerűen lehet dolgozni a set(), get() és remove() metódusok segítségével:

// változó írása
$section->set('userName', 'franta');

// változó kiolvasása, nullát ad vissza, ha nem létezik
echo $section->get('userName');

// változó eltávolítása
$section->remove('userName');

A foreach ciklussal a szakasz összes változóját megkaphatjuk:

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

Hogyan állítsuk be a lejáratot

A lejárat beállítható egyes szakaszokhoz vagy akár egyes változókhoz is. Engedhetjük, hogy a felhasználó bejelentkezése 20 perc múlva lejárjon, de a bevásárlókosár tartalmára továbbra is emlékezhetünk.

// a szakasz 20 perc múlva lejár
$section->setExpiration('20 minutes');

A set() metódus harmadik paramétere az egyes változók lejáratának beállítására szolgál:

// a 'flash' változó 30 másodperc múlva jár le
$section->set('flash', $message, '30 seconds');

Ne feledje, hogy a teljes munkamenet lejárati idejének (lásd a munkamenet konfigurációját) egyenlőnek vagy magasabbnak kell lennie, mint az egyes szakaszokhoz vagy változókhoz beállított idő.

A korábban beállított lejárati idő törlése a removeExpiration() módszerrel érhető el. A teljes szakasz azonnali törlését a remove() módszer biztosítja.

$onStart, $onBeforeWrite események

A Nette\Http\Session objektum rendelkezik $onStart a $onBeforeWriteeseményekkel, így olyan visszahívásokat adhat hozzá, amelyek a munkamenet elindulása után vagy a munkamenet lemezre írása, majd befejezése előtt hívódnak meg.

$session->onBeforeWrite[] = function () {
	// adatok írása a munkamenetbe
	$this->section->set('basket', $this->basket);
};

Munkamenet-kezelés

A Nette\Http\Session osztály munkamenet-kezelési metódusainak áttekintése:

start(): void

Munkamenetet indít.

isStarted(): bool

Elindult a munkamenet?

close(): void

A munkamenet befejeződik. A munkamenet automatikusan véget ér a parancsfájl végén.

destroy(): void

Befejezi és törli a munkamenetet.

exists(): bool

A HTTP-kérelem tartalmaz egy munkamenet-azonosítót tartalmazó sütit?

regenerateId(): void

Új véletlenszerű munkamenet-azonosítót generál. Az adatok változatlanok maradnak.

getId(): string

Visszaadja a munkamenet azonosítóját.

Konfiguráció

konfigurációban konfiguráljuk a munkamenetet. Ha olyan alkalmazást írsz, amely nem használ DI konténert, használd ezeket a módszereket a konfiguráláshoz. Ezeket a munkamenet elindítása előtt kell meghívni.

setName(string $name): static

Beállítja a munkamenet azonosítójának továbbítására használt süti nevét. Az alapértelmezett név PHPSESSID. Ez akkor hasznos, ha több különböző alkalmazást futtat ugyanazon a webhelyen.

getName(): string

Visszaadja a munkamenet süti nevét.

setOptions(array $options)static

A munkamenet konfigurálása. Lehetőség van az összes PHP munkamenet direktíva beállítására (camelCase formátumban, pl. session.save_path helyett savePath írása), valamint readAndClose.

setExpiration(?string $time)static

Beállítja az inaktivitás idejét, amely után a munkamenet lejár.

setCookieParameters(string $path, ?string $domain=null, ?bool $secure=null, ?string $samesite=null)static

A sütik paramétereinek beállítása. Az alapértelmezett paraméterértékeket a configuration#Session cookie menüpontban módosíthatja.

setSavePath(string $path)static

Beállítja a munkamenetfájlok tárolási könyvtárát.

setHandler(\SessionHandlerInterface $handler)static

Beállítja az egyéni kezelőt, lásd a PHP dokumentációt.

Első biztonság

A kiszolgáló feltételezi, hogy ugyanazzal a felhasználóval kommunikál, amíg a kérések ugyanazt a munkamenet-azonosítót tartalmazzák. A biztonsági mechanizmusok feladata annak biztosítása, hogy ez a viselkedés valóban működjön, és ne legyen lehetőség az azonosító kicserélésére vagy ellopására.

Ezért a Nette Framework megfelelően konfigurálja a PHP direktívákat, hogy a munkamenet-azonosítót csak sütikben továbbítsa, hogy elkerülje a JavaScriptből való hozzáférést, és hogy figyelmen kívül hagyja az URL-ben szereplő azonosítókat. Sőt, kritikus pillanatokban, például a felhasználó bejelentkezésekor új munkamenet-azonosítót generál.

Az ini_set függvényt a PHP konfigurálására használják, de sajnos egyes webtárhely-szolgáltatóknál tilos a használata. Ha ez a te eseted, próbáld meg kérni a tárhelyszolgáltatódat, hogy engedélyezze neked ezt a funkciót, vagy legalábbis megfelelően konfigurálja a szerverét.