Ü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.

verzió: 4.0