Ü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()
.
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 $onBeforeWrite
esemé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ó
A 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.