Nette Http 3.1: mnohem chytřejší sessions
Nette vždy přistupovalo k session opatrným způsobem. Spouštělo je automaticky až když je uživatel potřeboval. Což konkrétně znamená:
- když do ní zapisoval
- když z ní četl a zároveň existovalo cookie se session ID
Protože pokud cookie neexistuje, nemusíme session spouštět, abychom věděli, že v ní žádná data nejsou. Tedy bez spuštění může Nette vrátit obsah nákupního košíku jako prázdný atd.
S automatickým spouštěním souvisí problém pozdního nastartování
session, tedy v době, kdy už byl odeslán ze serveru výstup a již nelze
posílat HTTP hlavičky. Při spuštění session se totiž odesílá cookie se
session ID a také hlavičky Pragma
a Expires
. Aby se
tento problém minimalizoval, Nette při nastavení autoStart: smart,
což je výchozí, automaticky při startu spustilo session, pokud existovalo
cookie se session ID.
Celé to má ovšem určitá úskalí, které verze 3.1.5 řeší.
Přístup k datům
K datům v session sekci se často přistupuje jako k proměnným:
$section = $session->getSection('unique name');
$section->userName = 'john';
echo $section->userName;
Kvůli specifickému technickému rysu PHP je však operace
echo $section->userName
detekována jako zápis. Tím pádem
i výše zmíněné přečtení košíku $cart= $section->cart
nastartuje session i když cookie neexistuje. Což kazí efektivitu
autostartu.
Toto by bylo možné obejít použitím ArrayAccess syntaxe:
$section['userName'] = 'john';
echo $section['userName']; // jde o operaci čtení
Nicméně syntaxe ArrayAccess může být uživatele příliš magická a
někdy nefunguje tak, jak by se mohlo očekávat (např.
$section['cart'][] = $item
generuje notice Indirect
modification of overloaded element has no effect). Proto v posledních
verzích řady 3.1 i 3.0 najdete pro přístup k datům srozumitelnou sadu
metod set()
, get()
a remove()
. Pomocí
set()
lze nastavit i expiraci:
$section->set('flash', $message, '30 seconds');
Používání těchto metod se tak stává preferovaným přístupem k datům v sessions.
Autostart, když existuje cookie
Nette upravuje chování v situaci, když se ukáže, že session ID je neplatné, tj. když neexistuje odpovídající soubor na disku apod. Nette takovou situaci odhalilo a vygenerovalo nové ID a čistý soubor, aby předešlo možnému podvržení ID ze strany útočníka. Nyní místo toho naopak cookie smaže a soubor vůbec nevytváří. Důvod je ten, aby se na disku nevytvářely prázdné soubory, pokud útočník záměrně session ID podvrhává.
Nová konfigurace autoStart
Volba autoStart
může nově nabývat hodnot always
a never
. První z nich zapíná session vždy hned po startu a je
totožná s variantou true
. Novinkou je never
, která
zcela vypíná automatické startování a session se zapne jen tehdy, pokud
zavoláte $session->start()
. Výchozí variantou zůstává
smart
, která jak bylo uvedeno výše, už nezapíná session po
startu, ale až v případě čtení nebo zápisu. Je vlastně tak totožná s
false
.
V řadě v3.0 se mění výchozí nastavení ze smart
na
false
, což také vypíná autostart po spuštění.
Události $onStart, $onBeforeWrite
A nakonec objekt Nette\Http\Session
má nově události
$onStart
a $onBeforeWrite
, můžete tedy přidat
callbacky, které se vyvolají po startu session nebo před jejím zápisem na
disk a následným ukončením.
$session->onBeforeWrite[] = function () {
// zapíšeme data do session
$this->section->set('basket', $this->basket);
};
Při testování nového chování nezapomeňte, že ve vývojářském režimu startuje session Tracy, protože ji používá pro zobrazování pruhů s přesměrováním a AJAXovými požadavky v Tracy Baru.
Chcete-li odeslat komentář, přihlaste se