EN | CS | Přihlásit | Registrovat

Nette\Web\Session

U webových aplikací je často potřeba uchovávat některé informace, např. o přihlášení uživatele nebo obsahu nákupního košíku, mezi načtením jednotlivých stránek. K tomuto účelu existují session neboli relace. Každý uživatel, který vstoupí na stránku, obdrží jedinečný identifikátor Session ID a ten se předává v cookies. Ten pak slouží jako klíč k session datům. Narozdíl od cookies, které se uchovávají na straně prohlížeče, jsou data v session uchovávána na straně serveru.

V Nette ke správě session slouží třída Nette\Web\Session a manipulaci s daty zajišťuje Nette\Web\SessionNamespace. Pro oddělení vzájemně nesouvisejících session dat se tedy používají jmenné prostory, ve kterých se s nimi pracuje podobně jako s běžným polem v PHP.

Příklad – čítač přístupů

Začněme příkladem počítadla, které ukazuje, kolikrát uživatel zobrazil stránku:

// získáme přístup do jmenného prostoru counter
$namespace = Environment::getSession('counter');

// pokud v něm existuje proměnná $count
if (isset($namespace->count)) {
// zvětšíme její hodnotu o jedničku
$namespace->count++;
} else {
// jinak ji inicializujeme
$namespace->count = 1;
}

echo 'Počet zhlédnutí: ', $namespace->count;

A teď se podíváme na celou věc pozorněji. Získání přístupu do jmenného prostoru counter:

$session = Environment::getSession();

$namespace = $session->getNamespace('counter');

nebo stručněji

$namespace = Environment::getSession('counter');

Proměnné ve jmenném prostoru

Proměnné se používají jako obyčejné proměnné objektu:

$namespace->a = 'apple';
$namespace->p = 'pear';
$namespace->o = 'orange';

echo $namespace->a;

Pro získání všech proměnných z namespace je možné použít cyklus foreach.

foreach ($namespace as $key => $val) {
echo "$key = $val<br>";
}

Zrušení proměnné:

unset($namespace->a);

Nastavení expirace

Proměnná a bude smazána po 5 sekundách:

$namespace->setExpiration(5, 'a');

Celý jmenný prostor bude zrušen po uplynutí 60 sekund:

$namespace->setExpiration(60);

Celý jmenný prostor bude zrušen v okamžiku, kdy uživatel zavře okno prohlížeče.

$namespace->setExpiration(0);

Zrušení expirace celého jmenného prostoru (neovlivní explicitně nastavenou expiraci klíče a)

$namespace->removeExpiration();

Expirace proměnné se dá před vypršením zrušit:

$namespace->removeExpiration('a');

Okamžité zrušení celého jmenného prostoru:

$namespace->remove();

Práce se jmennými prostory

Vypsání všech prostoru a jejich proměnných:

$session = Environment::getSession();

foreach ($session as $name) {
echo "<h2>Namespace $name</h2>";
foreach (Environment::getSession($name) as $key => $val) {
echo "<h3>$key</h3>";
Debug::dump($val);
}
}

Ověření existence prostoru:

$session = Environment::getSession();
$session->hasNamespace('test'); // TRUE

Konfigurace session

Pro dlouhodobé uchování session proměnných je nutné mít nastavenou expiraci celé session a to nejlépe v bootstrapu.

Pokud se neprovede toto nastavení, všechny session proměnné vyexpirují v momentě zavření okna prohlížeče. Uchování session i po zavření prohlížeče se hodí například pro dlouhodobé přihlášení uživatele.

$session = Environment::getSession();

// sezení vyprší po 14 dnech neaktivity
$session->setExpiration('+ 14 days');

// sezení vyprší jakmile uživatel zavře prohlížeč
$session->setExpiration(0);

// nastavení cesty pro ukládání session dat na serveru
// soubory session se hromadí v tomto adresáři, udržuje ho garbage collector
$session->setSavePath(dirname(__FILE__) . '/sessions/');

// volitelné nastavení parametrů cookie
$session->setCookieParams($path, $domain = NULL, $secure = NULL);

Platnost autentizace na subdoménách

Platnost autentizace lze jednoduše rozšířit na subdomémy nastavením session.

Environment::getSession()->setOptions(array(
'cookie_path ' => '/', // cookie is available within the entire domain
'cookie_domain' => '.example.com', // cookie is available on all subdomains
));

Nastavení parametrů cookie musí být provedeno před tím, než je sezení otevřeno (lze zjistit přes Environment::getSession()->isStarted(). Pozdější volání nemá efekt. Sezení se otevírá například při přístupu ke jmennému prostoru (třeba voláním $namespace = Environment::getSession('myapp'), nebo používáním třídy User).

Session není možné startovat dvakrát (tedy je, ale musí se předtím manuálně uzavřít). Tudíž místo $session->start() je vhodnější používat třeba na:

if (!$session->isStarted()) $session->start();

Tipy k Vašim aplikacím

  • při zavření prohlížeče nechejte vypršet přihlášení uživatele, obsah košíku, oslovení je vhodné nechat
  • zobrazení informačních hlášek o úspěšnosti nějaké akce (například v administraci) je dobré vázat na nějakou session proměnnou v kombinaci s query-stringem. Proměnné v session nastavíme expiraci například 1 minutu a při zobrazení informační hlášky kontrolujeme existenci této proměnné a na základě toho se rozhodneme, zda-li hlášku ještě zobrazit/nezobrazit

Viz také:


Login to submit a comment