Sessions ve světle superglobálních proměnných

26. června 2003

Před nedávnem jsem se zde na Inteval.cz zabýval problematikou superglobálních proměnných a hlavně získávání hodnot z různých zdrojů. Ukázalo se totiž, že mnoho (nejen) začínajících programátorů v PHP má v této oblasti značné mezery. V podobném duchu bude i tento článek, zabývající se problematikou sessions, ve kterém vám dokáži, že používání sessions v novějších verzích PHP je jednodušší než kdykoliv předtím.

Ve starších verzích PHP jsem měl občas pocit, že používání sessions je spíše za trest. Naštěstí v nových verzích jsou sessions velmi dobře ošetřeny a výborně použitelné. V tomto článku předpokládám použití PHP 4.1.0 a vyšší, podporující superglobální pole. Pokud si nejste v této problematice úplně jisti, doporučuji vám již zmiňovaný článek o superglobálních proměnných. V následujících odstavcích budu mlčky předpokládat jejich znalost.

Sessions – co to je a k čemu je to dobré

Sessions (česky relace, v tomto textu se budu držet anglického označení) představují prostředek, jak mezi jednotlivými přístupy zachovávat a předávat data. V určitých případech je totiž nanejvýš potřebné, abychom měli k dispozici silný a zároveň jednoduchý mechanismus, který nám umožní pro každého uživatele uchovávat specifické údaje.

Typickým příkladem použití sessions je přihlašování uživatelů. Celý proces vypadá přibližně následovně: „Uživatel ve formuláři vyplní své jméno a heslo. Pokud údaje souhlasí, vytvoří se session a do ní se uloží jednoznačná informace identifikující našeho uživatele (například jeho id nebo jméno). Po celou dobu, po kterou se přihlášený uživatel pohybuje uvnitř systému, mají PHP aplikace přístup k informacím v session, tedy mohou určit, kdo je zrovna nalogovaný. Na konci práce se uživatel odhlásí a session je zničena.“ Výhodou tohoto postupu je skutečnost, že citlivá data jsou uložena na serveru. Aplikace si mezi sebou pouze předávají standardními mechanismy (cookies, get, post) id session, automaticky vygenerovaný jednoznačný identifikátor dané session.

Spuštění session

Ke spuštění session slouží funkce session_start(). Ta nejdříve zkontroluje, zda bylo aplikaci předáno jméno nějaké již probíhající session. Pokud ne, je vytvořena nová session. V opačném případě je znovu spuštěna předaná probíhající session. Všechna data jsou uložena v superglobálním poli $_SESSION[]. Protože session_start() ve většině případů vytváří cookie (viz dále), měla by být spouštěna ještě předtím, než jsou klientovi odeslána jakákoli data.

Máme tedy spuštěnou session a k dispozici pole $_SESSION[]. Zde se již naplno projeví výhody nových verzí PHP a superglobálních polí. Pokud chceme přidat do session nějaká data, uděláme to zcela jednoduše a přirozeně tak, že je přidáme do pole $_SESSION[]. Chtějme například předávat mezi aplikacemi proměnnou user s hodnotou 10: $_SESSION["user"]=10. Jak jistě tušíte, zcela ve stejném duchu se nese modifikace dat v session. Opět stačí změnit hodnotu daného prvku pole. No a pokud chceme některá data ze session vyřadit, stačí zrušit příslušný řádek. Následující kód zapříčiní vyjmutí proměnné user ze session: unset($_SESSION["user"]);.

Předávání jména session

Nyní již umíme spustit session a modifikovat její obsah. To nejdůležitější a také nejnáročnější (alespoň zdánlivě) nás ale stále čeká. Musíme nějakým způsobem předávat id naší session. Nejlepší případ nastane, pokud lze použít cookie. Ne všichni uživatelé ale mají cookies povoleny, proto by aplikace měla být schopna předávat id session i pomocí URL. Zatímco ve starších verzích se o toto vše musel starat programátor sám, nyní se naopak o vše postará PHP.

PHP totiž poskytuje konstantu SID, která nabývá hodnoty prázdného řetězce, pokud se funkci session_start() podařilo vytvořit cookie obsahující id session, nebo hodnoty ve tvaru jmeno_session=id_session, pokud má uživatel cookie zakázáno. Nyní pouze stačí do všech odkazů automaticky doplňovat na konec konstantu SID:

<a href=“www.nejaky_server.cz?<?php echo(SID); ?>“>odkaz</a>

Jak tedy celý proces bude vypadat? Funkce session_start() si sama zjistí, zda je k dispozici cookie. Pokud ano, uloží do ní hodnotu id session a konstanta SID nabude hodnoty prázdného řetězce. Pokud jsou cookies zakázány, uloží do konstanty SID hodnotu jmeno_session=id_session. V prvním případě bude náš vzorový odkaz vypadat takto: <a href="www.nejaky_server.cz?">odkaz</a>, v druhém případě například takto: <a href="www.nejaky_server.cz?PHPSESSID=29e1e4e306f6174f1ff6360fac75b18a">odkaz</a>.

Jak jste si asi všimli, jedinou skutečnou starostí programátora při předávání id session je doplňovat konstantu SID na konce všech odkazů a případně do formulářů. O zbytek se stará PHP!

Mazání session

Nyní již zbývá poslední drobnost, session při odhlášení smazat. K tomu slouží funkce session_destroy(). Aby mohla být session úspěšně smazána, je ji nutno nejdříve spustit pomocí session_start(). Funkce session_destroy() nesmaže položky pole $_SESSION[], o to se programátor musí postarat sám, například pomocí $_SESSION=array(); nebo v našem konkrétním případě unset($_SESSION["user"]);.

Některé užitečné funkce a direktivy PHP

V předchozích odstavcích jsme si popsali základní chování a pravidla konstrukce sessions. PHP mimo zmíněných možností nabízí i mnohé další, občas celkem užitečné. Podívejme se na ně podrobněji.

Direktiva session.name (direktivy jsou umístěny v konfiguračním souboru php.ini) obsahuje jméno sessions. Standardně má hodnotu PHPSESSID, což také znamená, že normálně má konstanta SID tvar PHPSESSID=id_session. Pro práci se jménem session existuje funkce session_name(), jejíž návratová hodnota obsahuje jméno dané session. Co je ale důležitější, může i jméno session nastavit na hodnotu předanou jako nepovinný argument. V tomto případě ale musíte session_name() vždy zavolat ještě před funkcí session_start().

V podobném duchu se nese funkce session_id(), která jako návratovou hodnotu vrací id konkrétní session. Také může mít nepovinný argument, kterým lze nastavit dané session nový id. Podobně jako u předchozí funkce je nutno session_id() v tomto případě volat ještě před nastartováním session.

Další dvě direktivy ovlivňují práci s cookies. Direktiva sessions.use_cookies určuje, jestli budou standardně použity cookies k ukládání id session. Implicitně je nastavena na 1. Podstatnější je druhá direktiva sessions.use_only_cookies, která povoluje předání session id pouze pomocí cookies. Předání pomocí cookies je totiž mnohem bezpečnější než jinými metodami. Přesto je nastavena na 0, takže i uživatelé se zakázanými cookies mohou používat vaše sessions (samozřejmě, pokud jim to sami umožníte).

Poměrně často diskutované je použití direktivy session.use_trans_sid. Po jejím povolení PHP automaticky doplní do všech odkazů id session. Přestože je tato direktiva implicitně vypnuta, na spoustě serverů je povolena. Co její použití tedy znamená? Pokud nejsou povoleny cookies, je id session automaticky doplněn do všech odkazů. Programátor se tedy v tomto případě nemusí vůbec starat o přenášení id session z jedné stránky na druhou! Já osobně tuto možnost vůbec nevyužívám, raději mám doplňování odkazů plně pod svou kontrolou. Navíc se může stát, že id session může být doplněn i do odkazu mířícího ven ze systému a může tak být prozrazen. Pokud budete své stránky provozovat na hostingu, kde bude session.use_trans_sid zapnuto a vy automatické doplňování nebudete chtít využívat, jednoduše přidejte na začátek každé stránky ini_set("session.use_trans_sid","0");.

Direktiv a funkcí okolo sessions je samozřejmě více, ty výše zmíněné mi přišly jako nejdůležitější. Pokud chcete prozkoumat všechna myslitelná zákoutí problematiky zvané sessions a jejího nastavování, doporučuji vám přečíst si dokumentaci. Platí však, že většinou bohatě stačí uvedené možnosti.

Starší komentáře ke článku

Pokud máte zájem o starší komentáře k tomuto článku, naleznete je zde.

Štítky: Články

Mohlo by vás také zajímat

Nejnovější

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *