Download as pdf or txt
Download as pdf or txt
You are on page 1of 26

poglavlje 18



Rukovanje sesijama

dana{nje vreme, kori{}enje HTTP sesija za pra}enje perzistentnih informacija, kao {to

U su korisni~ka pode{avnaja, ~ak i u najjednostavnijim aplikacijama predstavlja vi{e prav-


ilo, nego izuzetak. Zbog toga, nezavisno od toga da li ste po~etnik u razvoju web
aplikacija, ili ste iskusan veteran koji je do sada koristio neki drugi programski jezik, trebalo bi
da posvetite neko vreme pa`ljivom ~itanju ovog poglavlja.

U programskom jeziku PHP rukovanje sesijama je dostupno od verzije 4.0 i predstavlja jednu
od najinteresantijih funkcionalnosti, o kojoj se uvek mnogo diskutuje. U ovom poglavlju mo`ete
nau~iti dosta o rukovanju sesijama, izme|u ostalog:

 Zbog ~ega je neophodno rukovanje sesijama i koja je prednost rukovanja sesijama

 Kako da konfiguri{ete PHP okru`enje, tako da na najefikasniji mogu}i na~in rukujete


sesijama

 Kako da kreirate i uni{tavate sesije, odnosno kako da upravljate promenljivama vezan-


im za odre|ene sesije

 Zbog ~ega mo`ete da razmotrite mogu}nost upravljanja podacima o sesijama


kori{}enjem baze podataka, odnosno kako da to prakti~no realizujete

[ta se podrazumeva pod rukovanjem sesijom?


Hypertext Transfer Protocol (HTTP) defini{e pravila koja se primenjuju prilikom transfera teksta,
grafike, videa i svih drugih podataka putem Weba. To je protokol bez stanja, {to zna~i da se svaki
zahtev obra|uje nezavisno od bilo kog prethodnog ili budu}eg zahteva. Iako je HTTP veoma jed-
nostavan protokol, ~ime je omogu}ena njegova {iroka primena, njegova osobina da ne defini{e
stanja dugo je predstavljala veliki problem programerima koji su poku{avali da kreiraju veoma
slo`ene web aplikacije, koje moraju da imaju mogu}nost da pode{avaju odgovaraju}e
funkcionisanje prema korisni~kim zahtevima i preferencijama.

445
PHP i MySQL od po~etnika do profesionalca

Da bi se re{io ovaj problem, praksa sme{tanja odgovaraju}ih informacija na korisni~koj


ma{ini, koje se obi~no nazivaju kola~i}i, brzo je prihva}ena, ~ime je pojednostavljen postupak
upravljanja korisni~kim zahtevima u toku izvr{avanja aplikacije. Me|utim, ograni~enje vezano za
veli~inu kola~i}a i broj dozvoljenih kola~i}a, odnosno razli~ita pravila koja su vezana za njihovo
implementiranje, podstakll su programere da izmisle druga~ije re{enje: rukovanje sesijama.

Rukovanje sesijama je, u su{tini, veoma pametno re{enje, koje omogu}ava da se zaobi|e prob-
lem vezan za nepostojanje stanja u HTTP protokolu. Svaki posetilac stranice dobija atribut koji
ga jednozna~no identifikuje, poznat kao identifikator sesije (skra}eno SID), a zatim se svi
neophodni podaci povezuju sa tim jednozna~nim identifikatorom sesije, pri ~emu ti podaci
mogu odre|ivati ukupan broj poseta stranici na mese~nom nivou, omiljene boje pozadine ili
srednje slovo - vi ih defini{ete. Sa stanovi{ta relacionih baza podataka, identifikator sesije mo`ete
smatrati primernim klju~em koji se koristi za pristupanje svim ostalim atributima. Ali, na koji
na~in se identifikator sesije neprekidno vezuje za konkretnog korisnika, ukoliko se zna da je
HTTP protokol, zapravo, protokol koji ne defini{e stanja? To vezivanje, za konkretnog korisnika,
mo`ete da ostvarite na dva razli~ita na~ina:

 Kori{}enjem kola~i}a: Ovaj genijalan na~in za upravljanje informacijama o korisnici-


ma je, zapravo, vezan za originalan metod kori{}enja kola~i}a. Kada korisnik poseti
odgovaraju}u web stranicu, server bele`i odgovaraju}e informacije o korisniku, kao {to
su pode{avanja koja je korisnik izabrao, zatim te informacije u kola~i}u {alje do koris-
ni~kog ~ita~a, koji ih snima. Kada korisnik uputi zahtev za pristupanje nekoj drugoj
stranici, server o~itava korisni~ke informacije i koristi ih, na primer, za realizovanje
personalizovanog prikaza zahtevane stranice. Me|utim, umesto da se u kola~i}
sme{taju korisni~ka pode{avanja, sme{ta se identifikator sesije. Kako korisnik pristupa
razli~itim delovima web prezentacije, o~itava se identifikator sesije kada je to
neophodno, a zatim se koriste odgovaraju}i podaci koji su vezani za taj identifikator
sesije i korisniku se prikazuju neophodni podaci. Pored toga, po{to kola~i} ostaje na
ra~unaru korisnika i nakon zavr{etka sesije, on mo`e biti o~itan i za vreme neke
naredne sesije, {to zna~i da se odr`ava perzistentnost ~ak i u du`em vremenskom
intervalu, u kome korisnik ne pristupa odgovaraju}oj web prezentaciji. Me|utim,
vodite ra~una o tome da je prihvatanje kola~i}a isklju~ivo u nadle`nosti korisnika,
tako da morate da budete spremni i na mogu}nost da korisnik ne dozvoljava da se
podaci snimaju u kola~i} na njegovom ra~unaru, ili da je nakon nekog vremena koris-
nik uklonio sve kola~i}e sa svoje ma{ine.

446
Rukovanje sesijama POGLAVLJE 18

 Modifikovanje URL adrese: Drugi metod koji se koristi za identifikaciju sesije je vezan
za postavljanje identifikatora sesije na kraj svake lokalne URL adrese zahtevane stran-
ice. Rezultat toga je automatsko prosle|ivanje identifikatora sesije svaki put kada
korisnik pritisne jedan od lokalnih linkova. Ovaj metod, poznat kao modifikovanje
URL adrese, uklanja mogu}nost da rukovanje sesija bude onemogu}eno zato {to koris-
nik ne dozvoljava upotrebu kola~i}a. Me|utim, postoje i odgovaraju}e posledice
primene ovakvog metoda. Prvo, modifikovanje URL adrese ne omogu}ava perzistent-
nost izme|u sesija, zato {to se proces automatskog postavljanja identifikatora sesije na
kraj URL adrese ne nastavlja kada korisnik napusti va{u web prezentaciju. Drugo, ni{ta
ne spre~ava korisnika da iskopira URL adresu u poruku i elektronskom po{tom je
po{alje nekom drugom korisniku; sve dok se ne prekine sesija, ona }e postojati i na
radnoj stanici primaoca ove poruke. Razmotrite potencijalne probleme koji mogu nas-
tati kada oba korisnika simultano pristupaju odre|enim sadr`ajima na va{oj
prezentaciji, a da pri tome koriste isti identifikator sesije, ili ukoliko primaoc poruke
koja sadr`i link ne treba da vidi odre|ene podatke kojima se mo`e pristupati u datoj
sesiji. Zbog toga se preporu~uje metodologija u kojoj se koriste kola~i}i. Me|utim,
isklju~ivo je na vama da defini{ete sve prednosti i nedostatke oba navedena metoda, i
da na kraju odlu~ite {ta vam je ~initi.

Proces rukovanja sesijama


Po{to PHP mo`e biti konfigurisan tako da autonomno upravlja celokupnim procesom rukovan-
ja sesijama, uz neznatnu interakciju programera, mo`da }ete veliki broj podataka smatrati nebit-
nim. Me|utim, postoje potencijalne varijante podrazumevane procedure, koje zahtevaju od vas
bolje razumevanje celokupnog procesa, ~emu bi trebalo da posvetite posebnu pa`nju.

Prvi zadatak koji treba da izvr{i stranica na kojoj se obavlja rukovanje sesijama je utvr|ivanje
postojanja validne sesije, {to za posledicu ima kori{}enje postoje}e sesije ili iniciranje nove sesi-
je. Ukoliko ne postoji validna sesija, neophodno je inicirati novu sesiju i povezati je sa odgo-
varaju}im korisnikom, kori{}enjem jednog od metoda za prosle|ivanje identifikatora sesije, koji
su opisani u prethodnom odeljku. PHP omogu}ava identifikovanje postoje}e sesije
pronala`enjem identifikatora sesije, bilo u zahtevanoj URL adresi ili u kola~i}u. Me|utim, to
mo`ete da uradite i programskim putem. Na primer, ukoliko je naziv sesije sid, a ona je postavl-
jena iza odgovaraju}e URL adrese, vrednost mo`ete da o~itate na slede}i na~in:

$_GET['sid']

Ukoliko je identifikator sesije zabele`en u odgovaraju}em kola~i}u, mo`ete ga o~itati na slede}i


na~in:

$_COOKIE['sid']

447
PHP i MySQL od po~etnika do profesionalca

Nakon utvr|ivanja identifikatora sesije, mo`ete po~eti da bele`ite informacije vezane za dati
identifikator sesije, a mo`ete i da o~itate prethodno zabele`ene podatke za taj identifikator sesi-
je. Na primer, pretpostavimo da korisnik pregleda razli~ite novinske ~lanke na odgovaraju}oj
stranici. Identifikatori novinskih ~lanaka mogu da se pove`u sa odgovaraju}im identifikatorom
sesije, tako da mo`ete da napravite listu novinskih ~lanaka kojima je pristupio odgovaraju}i
korisnik, odnosno mo`ete da prika`ete tu listu ukoliko korisnik nastavi sa ~itanjem. U narednim
odeljcima }ete imati priliku da nau~ite kako da snimate, odnosno o~itavate odgovaraju}e
informacije vezane za konkretnu sesiju.

SAVET

Informacije o kola~i}ima mo`ete da o~itavate putem $_REQUEST superglobalne promenljive. Na primer, uko-
liko je naziv sesije sid, tada }ete pomo}u $_REQUEST odrediti identifikator sesije, kao da ste koristili $_COOK-
IE['sid']. Me|utim, da bi bilo jasnije, razmotrite kori{}enje superglobalne promenljive koja se na najbolji
na~in uklapa sa mestom nastanka promenljive.

Ovaj proces se nastavlja sve dok korisnik ne zatvori Web ~ita~ ili ne pristupi nekoj drugoj web
prezentaciji. Ukoliko se koriste kola~i}i, tada se defini{e trajanje kola~i}a tako {to se odredi neki
datum u budu}nosti, uz pretpostavku da }e korisnik ponovo pristupiti va{oj prezentaciji pre iste-
ka tog roka, ~ime }e sesija ostati nepromenjena, kao da korisnik nije ni napu{tao va{u web
prezentaciju. Ukoliko koristite modifikovanje URL adrese, sesija se zavr{ava onda kada korisnik
napusti stranicu, a nova sesija mora da po~ne slede}i put kada korisnik poseti stranicu. U nared-
nim odeljcima }ete imati priliku da nau~ite ne{to vi{e o konfiguracionim direktivama i funkcija-
ma koje su odgovorne za izvr{avanje prethodno opisanog procesa.

Konfiguracione direktive
Postoji skoro 30 konfiguracionih direktiva koje se koriste za rukovanje sesijama u programskom
jeziku PHP. Po{to mnoge od ovih direktiva igraju veoma zna~ajnu ulogu u utvr|ivanju
funkcionisanja celokupnog PHP okru`enja, trebalo bi da posvetite odre|eno vreme kako biste u
potpunosti ovladali ovim direktivama i mogu}im pode{avanjima. Najzna~ajnije direktive su
opisane u ovom odeljku.

Upravljanje medijumom za sme{tanje informacija o sesijama


session.save_handler direktivom se utvr|uje koli~ina informacija koja }e se bele`iti o odgovara-
ju}oj sesiji. Prototip ove funkcije je slede}eg oblika:

session.save_handler = files|mm|sqlite|user

Podaci o sesiji se mogu sme{tati na ~etiri na~ina: unutar obi~nih datoteka (files), u privre-
menoj memoriji (mm), kori{}enjem SQLite baze podataka (sqlite), ili putem korisni~ki defin-
isanih funkcija (user). Iako je podrazumevano pode{avanje vezano za sme{tanje podataka o sesi-
jama u obi~nim datotekama ne{to {to }e zadovoljiti zahteve vezane za veliki broj stranica, vodite

448
Rukovanje sesijama POGLAVLJE 18

ra~una o tome da aktivne web stranice mogu da imaju i po nekoliko hiljada datoteka sa podaci-
ma o sesijama, pa ~ak i nekoliko stotina hiljada takvih datoteka nakon odre|enog perioda
funkcionisanja.

Opcija vezana za kori{}enje privremene memorije je nabr`e re{enje za upravljanje podacima o


sesijama, ali je problem {to se za sme{tanje koristi RAM memorija. Sqlite opcija omogu}ava
kori{}enje novog SQLite pro{irenja, kako bi se informacijama o sesijama upravljalo transparent-
no, kori{}enjem ove baze podataka (vi{e informacija o SQLite bazi podataka mo`ete da
prona|ete u poglavlju 22). ^etvrta opcija, iako je najslo`enija za konfigurisanje, predstavlja
najfleksibilniju i najmo}niju opciju, zato {to korisni~ki definisani rukovaoci sesijama mogu da se
kreiraju tako da se informacije o sesijama sme{taju na medijumu koji defini{e programer. U
ovom poglavlju }ete imati priliku da nau~ite kako da koristite ovu opciju za sme{tanje podataka
o sesijama u odgovaraju}oj MySQL bazi podataka.

Pode{avanje putanje za datoteke sesije


Ukoliko je pomo}u session.save_handler direktive definisano da se koriste datoteke za sme{tanje
podataka o sesiji, tada pomo}u session.save_path direktive morate da defini{ete kako }ete identi-
fikovati direktorijum za snimanje. Ova direktiva je slede}eg oblika:

session.save_path = string

Prema definiciji, session.save_path direktiva ima vrednost /tmp. Vodite ra~una o tome da direk-
torijum ne sme da bude postavljen u korenom direktorijumu servera, zato {to ovi podaci mogu
veoma jednostavno da budu prikazivani u Web ~ita~u. Pored toga, ovaj direktorijum mora da
bude dostupan za upisivanje.

Zbog pove}avanja efikasnosti, session.save_path direktivu mo`ete da defini{ete kori{}enjem


sintakse N;/putanja, gde je N ceo broj koji predstavlja broj poddirektorijuma koji su na nivou N
prilikom sme{tanja podataka o samoj sesiji. To je korisno, ukoliko session.save_handler direkti-
va defini{e kori{}enje datoteka, a va{a web prezentacija obra|uje veliki broj sesija, po{to je
omogu}eno mnogo efikasnije sme{tanje datoteka o sesijama u nekoliko razli~itih direktorijuma,
a ne u jednom, monolitnom direktorijumu. Ukoliko odlu~ite da iskoristite ovu funkcionalnost,
PHP ne}e automatski kreirati direktorijume umesto vas. Me|utim, korisnici Linux operativnog
sistema mogu da automatizuju proces izvr{avanjem skripta mod_files.sh, koji je lociran u
ext/session direktorijumu. Ukoliko koristite Windows operativni sistem, ovaj shell skript nije
podr`an, iako kreiranje kompatibilnosg skripta pomo}u VBScript jezika predstavlja veoma jed-
nostavan posao.

Automatsko omogu}avanje kori{}enja sesija


Prema definiciji, za odgovaraju}u stranicu }ete mo}i da koristite sesije jedino ukoliko se izvr{i
session_start() funkcija (koja }e detaljno biti opisana ne{to kasnije u toku ovog poglavlja).
Me|utim, ukoliko planirate da koristite sesije na celoj web prezentaciji, ovu funkciju mo`ete da

449
PHP i MySQL od po~etnika do profesionalca

izbegnete ukoliko setting session.auto_start direktivom defini{ete vrednost 1. Ova direktiva je


slede}eg oblika:

session.auto_start = 0|1

Jedna od posledica kori{}enja ove direktive je da se spre~ava sme{tanje objekata u toku sesije,
zato {to definicija klase mora da bude u~itana pre nego {to se po~ne sa sesijom, kako bi se
objekti ponovo kreirali. Po{to session.auto_start direktiva mo`e to da spre~i, neophodno je da
defini{ete vrednost 0 ukoliko `elite da upravljate objektima unutar sesija.

Definisanje naziva sesije


Prema definiciji, PHP koristi naziv sesije u obliku PHPSESSID. Me|utim, vi sasvim slobodno
mo`ete da menjate ovaj naziv kori{}enjem session.name direktive. Ova direktiva je slede}eg
oblika:

session.name = string

Kori{}enje kola~i}a ili modifikovanje URL adrese


Ukoliko `elite da rukujete sesijama korisnika u toku ve}eg broja poseta va{oj prezentaciji, treba-
lo bi da koristite kola~i}e, tako da identifikator sesije mo`e biti kasnije ponovo kori{}en. Ukoliko
se korisni~ki podaci koriste samo u toku jedne posete va{oj prezentaciji, tada }e biti sasvim
dovoljno da koristite modifikovanje URL adrese (iako i pri tome morate da vodite ra~una o
bezbednosnim problemima koji su vezani za modifikovanje URL adrese, a koji su navedeni u
toku ovog poglavlja). Metod koji }ete da koristite mo`ete da izaberete pomo}u using
session.use_cookies direktive. Ukoliko defini{ete vrednost 1 (podrazumevana vrednost), koristi}e
se kola~i}i za ~uvanje identifikatora sesije; ukoliko defini{ete vrednost 0, primenjiva}e se postu-
pak modifikovanja URL adrese. Ova direktiva je slede}eg oblika:

session.use_cookies = 0|1

Vodite ra~una o tome da, ukoliko je omogu}ena session.use_cookies direktiva, ne postoji


potreba da eksplicitno izvr{avate funkciju za pode{avanje kola~i}a (na primer, PHP funkciju
set_cookie()), zato {to se ovo automatski defini{e pomo}u bilioteke za upravljanje sesijama.
Ukoliko izaberete da koristite kola~i}e kao metod za pra}enje korisni~kih sesija, tada morate da
uzmete u razmatranje i nekoliko drugih direktiva koje su opisane u daljem tekstu.

Automatsko modifikovanje URL adrese


Ukoliko je session.use_cookies direktiva onemogu}ena, jedinstveni identifikator sesije korisnika
mora da bude postavljen u URL adresu, kako bi se obezbedilo prosle|ivanje identifikatora. Ovo
mo`e da se realizuje ili eksplicitno, ru~nim dodavanjem $SID promenljive na kraj svake URL
adrese, ili automatski, omogu}avanjem direktive session.use_trans_sid. Ova direktiva je slede}eg
oblika:

450
Rukovanje sesijama POGLAVLJE 18

session.use_trans_sid = 0|1

Ne iznena|uje da, ukoliko koristite modifikovanje URL adresa, treba da omogu}ite ovu direk-
tivu, kako biste eliminisali mogu}e ljudske gre{ke u procesu modifikovanja.

Pode{avanje trajanja sesije definisane kola~i}ima


session.cookie_lifetime direktiva utvr|uje period validnosti sesije definisane kola~i}em. Ova
direktiva je slede}eg oblika:

session.cookie_lifetime = integer

Vreme `ivota je definisano u sekundama, pa ukoliko kola~i} mo`e da se koristi jedan sat,
neophodno je da ceo broj bude 3600. Ukoliko je u direktivi naveden broj 0 (podrazumevana
vrednost), tada }e kola~i} da egzistira sve dok se ~ita~ ponovo ne startuje.

Pode{avanje validne URL putanje sesije definisane kola~i}em


Direktiva session.cookie_path koristi se za definisanje putanje na kojoj se kola~i} smatra valid-
nim. Kola~i} je validan i ukoliko se nalazi u svim direktorijumima ni`eg nivoa na definisanoj
putanji. Ova direktiva ima slede}i oblik:

session.cookie_path = string

Na primer, ukoliko je u direktivi naveden /, tada je kola~i} validan za celu web prezentaciju.
Navo|enje /books direktorijuma uzrokuje da kola~i} bude validan samo ukoliko se poziva unutar
http://www.example.com/books/ putanje.

Pode{avanje validnog domena sesije definisane kola~i}em


Direktiva session.cookie_domain utvr|uje domen za koji se kola~i} smatra validnim. Ova direkti-
va je neophodna zato {to spre~ava da se iz drugih domena omogu}i o~itavanje kola~i}a defin-
isanog u va{em domenu. Ova direktiva je slede}eg oblika:

session.cookie_domain = string

U slede}em primeru je prikazano njeno kori{}enje:

session.cookie_domain = www.example.com

451
PHP i MySQL od po~etnika do profesionalca

Ukoliko `elite da odgovaraju}a sesija bude dostupna u razli~itim poddomenima va{e web
prezentacije, recimo domenima customers. example.com, intranet.example.com i www2.example.com,
tada je neophodno da direktivu iskoristite na slede}i na~in:

Validacija sesija upu}ivanjem


Primena metoda modifikovanja URL adresa za prosle|ivanje identifikatora sesije omogu}ava da
konkretno stanje sesije mo`e da bude pregledano od strane velikog broja korisnika kopiranjem i
umno`avanjem odre|ene URL adrese. session.referer_check direktiva se koristi kako bi smanjila
ovu mogu}nost, navo|enjem podstringa koji ukazuje na korisnika. Ukoliko korisnik nije sadr`an
u navedenom stringu, to zna~i da identifikator sesije nije validan. Direktiva je slede}eg oblika:

session.referer_check = string

Pode{avanje mogu}nosti ke{iranja za stranice


koje se koriste u sesiji
Prilikom rada sa sesijama, mo`da }ete po`eleti da imate vi{i nivo kontrole nad stranicama koje
se mogu koristiti u sesijama, a koje se ke{iraju u ~ita~u korisnika, kao i u svim proksijima koji se
nalaze izme|u servera i korisnika. session.cache_limiter direktiva se koristi za modifikovanje
zaglavlja ovih ke{iranih stranica, ~ime se obezbe|uju instrukcije vezane za karakteristike ke{iran-
ja. Ova direktiva je slede}eg oblika:

session.cache_limiter = string

Mogu se koristiti slede}e vrednosti:

none: Ovim pode{avanjem se onemogu}ava prosle|ivanje svih kontrolnih zaglavlja


ke{a izme|u stranica koje se koriste u sesiji.

nocache: Ovo je podrazumevano pode{avanje. Ovim pode{avanjem se omogu}ava da


svaki zahtev bude prvo prosle|en do servera, pre nego {to bude ponu|ena potencijal-
no ke{irana verzija.

private: Ukoliko ke{irani dokument ozna~ite kao privatan, zna~i da }e dokument biti
raspolo`iv isklju~ivo originalnom korisniku. Ovaj dokument ne}e mo}i da se deli sa
drugim korisnicima.

private_no_expire: Ovo je varijacija prethodnog primera, pri ~emu sada ne postoji


definisano vremensko ograni~enje u ~ita~u. Ova vrednost se dodaje kako bi se pre-
vazi{ao problem vezan za Expire zaglavlje koje se {alje kada se direktiva koristi uz
navo|enje vrednosti private, {to mo`e da zbuni neke Web ~ita~e.

public: Ovo pode{avanje omogu}ava da se ke{iraju svi dokumenti, ~ak i kada je za


originalni dokument neophodna provera autenti~nosti.

452
Rukovanje sesijama POGLAVLJE 18

Definisanje vremena zastarevanja ke{a prilikom kori{}enja sesija


session.cache_expire direktiva koristi se prilikom definisanja vremenskog perioda, izra`enog u
sekundama (podrazumevana vrednost je 180 sekundi), u kome su ke{irane stranice raspolo`ive
pre kreiranja novih stranica. Ova direktiva je slede}eg oblika:

session.cache_expire = integer

Ukoliko session.cache_limiter direktiva ima vrednost nocache, direktiva se ignori{e.

Definisanje trajanja sesije


session.gc_maxlifetime direktiva se koristi za definisanje trajanja sesije, pri ~emu je trajanje
izra`eno u sekundama (podrazumevana vrednost iznosi 1440 sekundi), i u toku tog vremena se
sesija smatra validnom. Prototip ove direktive je slede}eg oblika:

session.gc_maxlifetime = ceobroj

Nakon {to istekne definisani vremenski interval, uklanjaju se sve informacije vezane za sesiju,
odnosno osloba|aju svi sistemski resursi, koji se mogu dodeljivati nekoj drugoj sesiji.

Kori{}enje sesija
U ovom odeljku su opisani brojni klju~ni zadaci vezani za rukovanje sesijama, koji se realizuju
pomo}u odgovaraju}ih funkcija za upravljanje sesijama. Neki od ovih zadataka podrazumevaju
kreiranje i uklanjanje sesija, definisanje i o~itavanje identifikatora sesije, odnosno sme{tanje i
o~itavanje promenljivih vezanih za sesije. U ovom uvodu su prikazane osnove neophodne za
razumevanje narednog odeljka, u kome su navedeni neki prakti~ni primeri vezani za upravljanje
sesijama.

Kreiranje sesije
Zapamtite da je HTTP protokol bez stanja, tako da ne sadr`i nikakve informacije o prethodnim
ili budu}im pona{anjima korisnika. Zbog toga je neophodno da eksplicitno inicirate sesiju, a
zatim je nastavite kada je to neophodno. Oba zadatka se realizuju pomo}u session_start() funkci-
je. Prototip ove funkcije je slede}eg oblika:

boolean session_start()

Izvr{avanjem session_start() funkcije kreira}e se nova sesija ukoliko nije definisan nijedan
identifikator sesije, ili }e se nastaviti prethodno zapo~eta sesija ukoliko postoji odgovaraju}i iden-
tifikator sesije. Ovu funkciju koristite veoma jednostavno, tako {to }ete je izvr{iti na slede}i na~in:

session_start();

Uo~ite da session_start() funkcija izve{tava o uspe{nom ishodu, nezavisno od rezultata. Zbog


toga je u ovoj situaciji dobro re{enje da koristite neki metod za rukovanje izuzecima.

453
PHP i MySQL od po~etnika do profesionalca

Izvr{avanje ove funkcije mo`ete da elimini{ete omogu}avanjem konfiguracione direktive


session.auto_start. Me|utim, vodite ra~una o tome da }ete time po~eti novu sesiju ili nastaviti
postoje}u sesiju za svaku PHP stranicu.

Uklanjanje sesije
Iako mo`ete da konfiguri{ete PHP direktive za rukovanje sesijama, kako bi se automatski ukloni-
la sesija nakon isteka unapred definisanog vremena za trajanje sesije ili na osnovu verovatno}e,
ponekad je mnogo korisnije da ru~no uklonite sesiju. Na primer, mo`da `elite da omogu}ite da
korisnik samostalno napusti stranicu tako {to se izloguje. Kada korisnik pritisne odgovaraju}i
link, vi mo`ete da uklonite iz memorije sve promenljive koje su vezane za tu sesiju, pa ~ak i da u
potpunosti uklonite podatke o sesiji sa odgovaraju}eg memorijskog medijuma, {to se realizuje
pomo}u funkcija session_unset() i session_destroy(), respektivno.

session_unset() funkcija se koristi za uklanjanje svih promenljivih vezanih za trenutnu sesiju,


pri ~emu se efektivno vra}a stanje sesije, koje je bilo nakon njenog kreiranja (nisu registrovane
promenljive vezane za sesiju). Prototip ove funkcije je slede}eg oblika:

void session_unset()

Iako se izvr{avanjem session_unset() funkcije zaista uklanjaju sve promenljive vezane za


trenutno aktivnu sesiju, sesija ne}e biti u potpunosti uklonjena sa odgovaraju}eg medijuma za
sme{tanje.

Ukoliko `elite da u potpunosti uklonite sesiju, neophodno je da upotrebite funkciju


session_destroy(), koja trenutnu sesiju progla{ava neva`e}om, a zatim je u potpunosti uklanja sa
medijuma za sme{tanje sesija. Vodite ra~una o tome da na ovaj na~in ne}ete ukloniti i kola~i}e
koji su sme{teni u korisni~kim ~ita~ima. Prototip ove funkcije je slede}eg oblika:

boolean session_destroy()

Ukoliko niste zainteresovani za kori{}enje kola~i}a nakon zavr{etka sesije, jednostavno


pomo}u session.cookie_lifetime direktive defini{ite vrednost 0 (podrazumevana vrednost) u
php.ini datoteci.

Definisanje i o~itavanje identifikatora sesije


Zapamtite da identifikator sesije, zapravo, povezuje sve podatke sesije sa konkretnim korisnikom.
Iako PHP omogu}ava autonomno kreiranje i prosle|ivanje identifikatora sesije, postoje situacije
u kojima mo`da `elite da ru~no postavite ili o~itate identitikator. Funkcija session_id() mo`e da
se koristi za izvr{avanje oba zadatka. Prototip ove funkcije je slede}eg oblika:

string session_id([string sid])

454
Rukovanje sesijama POGLAVLJE 18

Funkcija session_id() se mo`e koristiti i za definisanje i za o~itavanje vrednosti identifikatora


sesije. Ukoliko nije naveden opcioni parametar, funkcija session_id() vra}a identifikator
trenutno aktivne sesije. Ukoliko je naveden opcioni parametar sid, tada }e trenutna vrednost
identifkatora sesije biti zamenjena tom vredno{}u. Kori{}enje ove funkcije je prikazano u
slede}em primeru:

<?php
session_start();
echo "Your session identification number is ".session_id();
?>

Prilikom izvr{avanja ovog skripta dobija se slede}i rezultat:

Your session identification number is 967d992a949114ee9832f1c11c

Kreiranje i uklanjanje promenljivih sesije


Promenljive sesije se koriste za upravljanje podacima koji treba da budu vezani za korisnika, kako
on pristupa odgovaraju}im stranicama na va{oj prezentaciji. Me|utim, danas preporu~eni metod
podrazumeva jednostavno definisanje i uklanjanje ovih promenljivih na isti na~in kao {to se to
radi sa bilo kojom drugom promenljivom, osim {to je neophodno da uka`ete na njih u
kontekstu $_SESSION superglobalne promenljive. Na primer, pretpostavimo da `elite da defini{ete
promenljivu sesije koja se naziva username, {to je prikazano u slede}em skriptu:

<?php
session_start();
$_SESSION['username'] = "jason";
printf("Your username is %s.", $_SESSION['username']);
?>

Izvr{avanjem prethodnog primera dobija se slede}i rezultat:

Your username is jason.

Da biste uklonili promenljivu, neophodno je da iskoristite funkciju unset(), kao {to je


prikazano u slede}em primeru:

<?php
session_start();
$_SESSION['username'] = "jason";
printf("Your username is: %s <br />", $_SESSION['username']);
unset($_SESSION['username']);
printf("Username now set to: %s", $_SESSION['username']);
?>

455
PHP i MySQL od po~etnika do profesionalca

Izvr{avanjem prethodnog primera dobija se slede}i rezultat:

Your username is: jason


Username now set to:

UPOZORENJE

Mo`da }ete imati priliku da se susretnete sa nekim starijim dokumentima i diskusijama koje ukazuju na
funkcije session_register() i session_unregister(), koje su nekada bile preporu~eni na~in za kreiranje
i uklanjanje promenljivih vezanih za sesije, respektivno. Me|utim, zato {to ove funkcije zavise od konfigu-
racione direktive register_globals, koja je prema definiciji onemogu}ena po~ev{i od PHP verzije 4.2.0,
odnosno u potpunosti uklonjena u PHP verziji 6.0, umesto toga trebalo bi da koristite metode za dodelji-
vanje i uklanjanje promenljivih koji su opisani u ovom odeljku.

Kodiranje i dekodiranje podataka sesije


Nezavisno od medijuma kori{}enog za skladi{tenje, PHP sme{ta podatke o sesijama u standard-
izovanom formatu, koji se sastoji od odgovarajue}g stringa. Na primer, sadr`aj sesije sastoji se od
dve promenljive, username i loggedon, i slede}eg je oblika:

username|s:5:"jason";loggedon|s:20:"Feb 16 2008 22:32:29";

Svaka referenca na promenljivu sesije je izdvojena ta~kom i zarezom, i sastoji se od tri kom-
ponente: naziva, du`ine i vrednosti. Op{ti oblik sintakse je:

name|s:length:"value";

Na sre}u, PHP autonomno rukuje kodiranjem i dekodiranjem sesije. Me|utim, ponekad }ete
mo`da po`eleti da izvr{ite i ru~no ove zadatke. Na raspolaganju imate dve funkcije:
session_encode() i session_decode(), respektivno.

Kodiranje podataka sesije


session_encode() funkcija vam omogu}ava da na veoma jednostavan na~in ru~no kodirate sve
promenljive vezane za sesiju pomo}u jednog stringa. Prototip ove funkcije je slede}eg oblika:

string session_encode()

Nakon toga, ovaj string mo`ete da postavite u bazu podataka, odnosno mo`ete ga kasnije
o~itavati, odnosno dekodirati pomo}u session_decode() funkcije.

456
Rukovanje sesijama POGLAVLJE 18

Na primer, pretpostavimo da kola~i} sadr`i identifikator sesije korisnika i da je sme{ten na nje-


govom ra~unaru. U trenutku kada korisnik zahteva u~itavanje odgovaraju}e stranice koja sadr`i
slede}i listing, identifikator korisnika se o~itava iz kola~i}a. Ova vrednost se zatim tretira kao
identifikator sesije. Kreiraju se odgovaraju}e promenljive sesije, a zatim im se dodeljuje neophod-
na vrednost i nakon toga se sve ove informacije kodiraju kori{}enjem session_encode() funkcije,
~ime se pripremaju za unos u bazu podataka.

<?php
// Iniciranje sesije i kreiranje nekoliko promenljivih sesije
session_start();

// Definisanje vrednosti za nekoliko promenljivih sesije.


$_SESSION['username'] = "jason";
$_SESSION['loggedon'] = date("M d Y H:i:s");

// Kodiranje svih podataka sesije u jedan string i prikazivanje rezultata


$sessionVars = session_encode();
echo $sessionVars;
?>

Izvr{avanjem prethodnog koda dobija se slede}i rezultat:

username|s:5:"jason";loggedon|s:20:"Feb 16 2008 22:32:29";

Vodite ra~una o tome da session_encode() funkcija kodira sve promenljive sesije koje su
definisane za posmatranog korisnika, a ne samo one koje su vezane za konkretan skript u kome
se izvr{ava session_encode() funkcija.

Dekodiranje podataka sesije


Kodirani podaci vezani za sesiju se mogu dekodirati pomo}u session_decode() funkcije. Prototip
ove funkcije je slede}eg oblika:

boolean session_decode(string podaci_sesije)

Ulazni parametar podaci_sesije predstavlja kodirani string kojim su predstavljene promenljive


sesije. Funkcija se koristi za dekodiranje ovih promenljivih, pri ~emu se one vra}aju u provobit-
ni format, a izvr{avanjem ove funkcije dobija se vrednost TRUE ukoliko je dekodiranje uspe{no
obavljeno, odnosno vrednost FALSE, u suprotnom. Nastavljaju}i sa prethodnim primerom, pret-
postavimo da su neki podaci vezani za sesiju kodirani i postavljeni u bazu podataka, konkretno,
identifikator sesije i promenljive $_SESSION['username'] i $_SESSION['loggedon']. Slede}i skript se
koristi za o~itavanje tih podataka iz odgovaraju}e tabele baze podataka, odnosno njihovo
dekodiranje, ~ime se oni vra}aju u prvobitni oblik:

457
PHP i MySQL od po~etnika do profesionalca

<?php
session_start();
$sid = session_id();

// Kodirani podaci, koji su ocitani iz baze podataka, predstavljeni su u sledecem


obliku:
// $sessionVars = username|s:5:"jason";loggedon|s:20:"Feb 16 2008
22:32:29";

session_decode($sessionVars);

echo "User ".$_SESSION['username']." logged on at ".$_SESSION['loggedon'].".";

?>

Izvr{avanjem prethodnog skripta dobija se slede}i rezultat:

User jason logged on at Feb 16 2008 22:55:22.

Cilj ovog hipoteti~kog primera bio je da vam demonstrira kori{}enje PHP funkcija za kodiran-
je i dekodiranje. Ukoliko zaista `elite da snimate podatke vezane za sesije u bazu podataka, za to
postoji mnogo efikasniji metod, koji podazumeva definisanje odgovaraju}eg rukovaoca sesijama,
odnosno postavljanje tih rukovaoca direktno u API interfejs PHP okru`enja. Kako se ovo
realizuje, prikazano je kasnije u toku ovog poglavlja.

Prakti~ni primeri vezani za rukovanje sesijama


Po{to ste sada upoznati sa osnovnim funkcijama koje se koriste prilikom rukovanja sesijama,
spremni ste da razmotrite i neke realne primere. U prvom primeru opisan je postupak kreiranja
mehanizma koji automatski proverava autenti~nost i vra}a registrovane korisnike stranice. U dru-
gom primeru je prikazano kori{}enje promenljivih sesije u cilju kreiranja indeksa dokumenata
koje je prethodno pregledao odgovaraju}i korisnik. Oba primera su prili~no op{ta, ali to ne sme
da vas iznenadi, s obzirom na njihovu o~iglednu korist. Ono {to mo`e da vas iznenadi je jed-
nostavnost kreiranja ovakvih skriptova.

NAPOMENA

Ukoliko niste do sada koristili MySQL bazu podataka i zbunjeni ste sintaksom koja je iskori{}ena u slede}im
primerima, obratite pa`nju na tekst koji se nalazi u poglavlju 30.

458
Rukovanje sesijama POGLAVLJE 18

Automatsko prijavljivanje i prikazivanje korisnika


Nakon {to se korisnik prijavi, obi~no navo|enjem korisni~kog imena i {ifre, pomo}u kojih se
jednozna~no identifikuje taj korisnik, ~esto je zgodno da omogu}ite korisniku da se kasnije
ponovo vrati na stranicu, a da pri tome ne mora da ponovi postupak prijavljivanja. Ovo mo`ete
veoma jednostavno da ostvarite pomo}u sesija, nekoliko promenljivih vezanih za sesije i odgo-
varaju}e MySQL tabele. Iako postoji mnogo na~ina za implementiranje ove funkcionalnosti,
provera postoje}e promenljive vezane za sesiju (konkretno, $username promenljive) je sasvim
dovoljna. Ukoliko postoji ova promenljiva, korisnik mo`e automatski da pristupi stranici.
Ukoliko ova promenljiva ne postoji, prikazuje se odgovaraju}a forma za prijavljivanje.

NAPOMENA

Prema definiciji, session.cookie_lifetime konfiguraciona direktiva ima vrednost 0, {to zna~i da se kola~i}
uklanja prilikom restartovanja ~ita~a. Zbog toga bi trebalo da ovu vrednost promenite, tako da predstavlja
broj sekundi, kako biste omogu}ili da sesija postoji odgovaraju}i vremenski period.

MySQL tabela, pod nazivom users, prikazana je u listingu 18.1.

CREATE TABLE users (


id SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT,
username VARCHAR(10) NOT NULL,
pswd VARCHAR(10) NOT NULL,
PRIMARY KEY(id)
);

Kod (koji se nalazi u login.html datoteci) koji je prikazan u slede}em primeru, koristi se za
prikazivanje forme za prijavu, ukoliko ne postoji validna sesija za odgovaraju}eg korisnika:

<p>
<form method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>">
Username:<br /><input type="text" name="username" size="10" /><br />
Password:<br /><input type="password" name="pswd" SIZE="10" /><br />
<input type="submit" value="Login" />
</form>
</p>

Kona~no, logika koja se koristi za upravljanje procesom automatskog prijavljivanja je slede}eg


oblika:

459
PHP i MySQL od po~etnika do profesionalca

<?php

session_start();

// Da li je sesija prethodno inicirana?


if (! isset($_SESSION['username'])) {

// Ukoliko postoji prethodno inicirana sesija, da li je ona vezana


// za odgovarajuceg korisnika?
if (isset($_POST['username']))
{

$username = mysqli_real_escape_string($_POST['username']);
$pswd = mysqli_real_escape_string($_POST['pswd']);

// Povezivanje na MySQL server i selektovanje odgovarajuce baze podataka.


mysql_connect("localhost","webuser","secret");
mysql_select_db("chapter18");

// Pretraga odgovarajuceg korisnika u users tabeli.


$query = "SELECT username FROM users
WHERE username='$username' AND pswd='$pswd'";
$result = mysql_query($query);

// Da li je odgovarajuci korisnik pronadjen u users tabeli?


if (mysql_numrows($result) == 1)
{

$_SESSION['username'] = mysql_result($result,0,"username");
echo "You've successfully logged in. ";
}
// Ukoliko korisnik nije prethodno prijavljen na sistem, prikazuje se
forma za prijavljivanje.
} else {
include "login.html";
}

// Korisnik se vratio. Prikazati poruku dobrodoslice.


} else {
printf("Welcome back, %s!", $_SESSION['username']);
}
?>

460
Rukovanje sesijama POGLAVLJE 18

Po{to su danas korisnici zatrpani razli~itim korisni~kim imenima i {iframa, koje omogu}avaju
pristupanje razli~itim sistemima i kori{}enje razli~itih usluga, od provere elektronske po{te i
produ`avanja iznajmljivanja knjiga iz biblioteke, do pregledanja stanja na bankovnom ra~unu,
obezbe|ivanje automatskog prijavljivanja, kada to situacija dozvoljava, bi}e veoma dobro prih-
va}eno od strane korisnika va{e aplikacije.

Generisanje indeksa nedavno pregledanih dokumenata


Koliko puta ste se vratili na neku web prezentaciju, razmi{ljaju}i gde ste ta~no prona{li odgo-
varaju}e uputstvo vezano za programski jezik PHP, ~iju ste adresu zaboravili da zabele`ite? Da li
bi bilo korisno da web stranica zabele`i podatke o ~lancima koje ste prethodno pregledali, i da
vam te podatke prika`e kada vam je to neophodno? U slede}em primeru prikazana je ova
funkcionalnost.

Re{enje je iznena|uju}e jednostavno, ali je veoma efektno. Da biste zapamtili koja je doku-
menta ~itao posmatrani korisnik, neophodno je da pomo}u jedinstvenog identifikatora identi-
fikujete svakog pojedina~nog korisnika i svaki pojedina~ni dokument. Kada se radi o korisniku,
ovaj zahtev ispunjava identifikator sesije. Dokumenti se mogu identifikovati na koji god na~in
`elite, ali u ovom primeru se koristi naslov rada i URL adresa, odnosno pretpostavlja se da je ova
informacija definisana podacima koji se nalaze u bazi podataka, u tabeli articles, koja je slede}eg
oblika:

CREATE TABLE articles (


id SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT,
title VARCHAR(50),
content MEDIUMTEXT NOT NULL,
PRIMARY KEY(id)
);

Jedini neophodan zadatak je sme{tanje identifikatora ~lanaka u promenljivama sesije, koji su


implementirani na slede}i na~in:

<?php
// Kreiranje nove sesije
session_start();
// Povezivanje na server i selektovanje baze podataka
mysql_connect("localhost","webuser","secret");
mysql_select_db("chapter18");
// Ocitavanje zeljenog identifikatora clanka
$articleid = mysqli_real_escape_string($_GET['id']);

461
PHP i MySQL od po~etnika do profesionalca

// Korisnik zeli da pregleda clanak, pa se ocitava iz baze podataka


$query = "SELECT title, content FROM articles WHERE id='$id'";
$result = mysql_query($query);

// Prikazivanje rezultata izvrsavanja upita


list($title, $content) = mysql_fetch_row($result);

// Dodavanje naslova clanka i linka u listu


$articlelink = "<a href='article.php?id=$id'>$title</a>";
if (! in_array($articlelink, $_SESSION['articles']))
$_SESSION['articles'][] = $articlelink;

// Prikazivanje liste zahtevanih clanaka


echo "<p>$title</p><p>$content</p>";
echo "<p>Recently Viewed Articles</p>";
echo "<ul>";

foreach($_SESSION['articles'] as $doc) echo "<li>$doc</li>";


echo "</ul>";
?>

Izvr{avanjem prethodnog primera dobija se rezultat sli~an onom koji je prikazan na slici 18.1.

SLIKA 18.1 Pra}enje dokumenata koje je pregledao korisnik

Kreiranje proizvoljnog rukovaoca sesijama


Korisni~ki definisani rukovaoci sesijama nude veliku fleksibilnost u odnosu na ~etiri metoda za
sme{tanje. Implementiranje proizvoljnog rukovaoca sesijama je iznena|uju}e jednostavno, a ost-
varuje se u nekoliko koraka. Da biste po~eli njegovo kreiranje, neophodno je da izvr{ite {est

462
Rukovanje sesijama POGLAVLJE 18

zadataka (definisanih u daljem tekstu) vezanih za kori{}enje lokacija za sme{tanje. Pored toga,
neophodno je da defini{ete parametre za svaku pojedina~nu funkciju, nezavisno od toga da li
va{a konkretna implementacija koristi parametar. U ovom odeljku definisana je namena i struk-
tura ovih {est funkcija. Pored toga, opisana je i session_set_save_handler() funkcija, koja se koristi
za magi~no transformisanje funkcionisanja PHP rukovaoca sesijama u ono {to ste definisali
odgovaraju}im funkcijama. Kona~no, ovaj odeljak sadr`i demonstraciju ove funkcionalnosti,
koja je implementirana pomo}u MySQL baze podataka. Ovu biblioteku mo`ete da koristite u
svojim aplikacijama, koriste}i MySQL tabelu kao primarnu lokaciju za sme{tanje informacija o
pojedina~nim sesijama.
session_open($session_save_path, $session_name): Ova funkcija inicijalizuje sve elemente
koji mogu da se koriste u toku sesije. Dva ulazna parametra, $session_save_path i $ses-
sion_name, ukazuju na istoimene konfiguracione direktive, koje se nalaze u php.ini
konfiguracionoj datoteci. PHP funkcija get_cfg_var() se koristi za o~itavanje ovih kon-
figuracionih vrednosti u nekim od primera koji slede.
session_close(): Ova funkcija funkcioni{e sli~no standardnim funkcijama za rukovan-
je, pri ~emu se osloba|aju svi resursi koji su zauzeti pomo}u session_open() funkcije.
Kao {to mo`ete da primetite, ne postoje ulazni parametri za ovu funkciju. Vodite
ra~una o tome da na ovaj na~in ne}ete u potpunosti ukloniti sesiju. To je posao ses-
sion_destroy() funkcije, koja je opisana na kraju ove liste funkcija.
session_read($sessionID): Ova funkcija se koristi za o~itavanje podataka vezanih za
sesiju, koji su sme{teni na nekom medijumu. Ulazni parametar, $sessionID, ukazuje na
identifikator sesije koji }e se koristiti prilikom identifikovanja podataka vezanih za
konkretnog korisnika.
session_write($sessionID, $value): Ova funkcija se koristi za upisivanje podataka,
vezanih za odgovaraju}u sesiju, na meki medijum za sme{tanje. Ulazni parametar,
$sessionID, je naziv promenljive, a ulazni parametar $sessionID, defini{e podatke
vezane za odgovaraju}u sesiju.
session_destroy($sessionID): Ova funkcija je verovatno poslednja koju }ete izvr{avati u
va{em skriptu. Ona se koristi za uklanjanje sesije i svih promenljivih koje su vezane za
tu sesiju. Ulazni parametar $sessionID ukazuje na identifikator sesije, kojim je defin-
isana trenutno aktivna sesija.
session_garbage_collect($lifetime): Ova funkcija se koristi za efikasno uklanjanje
svih sesija, ~ije je vreme trajanja isteklo. Ulazni parametar $lifetime ukazuje na ses-
sion.gc_maxlifetime konfiguracionu direktivu sesije, koja se nalazi u php.ini datoteci.

Kori{}enje definisanih funkcija za rukovanje sesijama u PHP kodu


Nakon {to defini{ete {est funkcija za rukovanje, neophodno je da ih pove`ete u jedinstvenu
logiku za upravljanje sesijama u programskom jeziku PHP. To se realizuje prosle|ivanjem nazi-
va ovih funkcija do session_set_save_handler() funkcije. Vodite ra~una o tome da nazive mo`ete

463
PHP i MySQL od po~etnika do profesionalca

sasvim proizvoljno da dajete, ali da morate da defini{ete odgovaraju}i broj i tip parametara,
kao {to je navedeno u prethodnom odeljku, i da oni moraju biti prosle|eni do
session_set_save_handler() funkcije, u slede}em redosledu: open, close, read, write, destroy i
garbage collect.

U slede}em primeru prikazano je kori{}enje ove funkcije:

session_set_save_handler("session_open", "session_close", "session_read",


"session_write", "session_destroy",
"session_garbage_collect");

U narednom odeljku prikazano je kreiranje rukovaoca koji upravljaju informacijama o sesija-


ma pomo}u MySQL baze podataka.

Kori{}enje rukovalaca sesijama, koji koriste


podatke iz MySQL baze podataka
Pre nego {to koristite rukovaoce sesijama, koji koriste podatke iz MySQL baze podataka,
neophodno je da izvr{ite dva zadatka:

1. Kreiranje baze podataka i tabele koja se koristi za sme{tanje podataka o sesijama.

2. Kreiranje {est funkcija za rukovanje sesijama.

Slede}a MySQL tabela, sessioninfo, koristi se za sme{tanje podataka vezanih za sesije. Kada se
radi o ovom konkretnm primeru, pretpostavimo da se ova tabela nalazi u odgovaraju}im sesija-
ma za rad sa bazama podataka, iako ovu tabelu mo`ete da postavite gde god `elite.

CREATE TABLE sessioninfo (


SID CHAR(32) NOT NULL,
expiration INT NOT NULL,
value TEXT NOT NULL,
PRIMARY KEY(SID)
);

Listing 18.2 sadr`i definisane MySQL funkcije za rad sa sesijama. Uo~ite da su definisani svi
neophodni rukovaoci, da je obezbe|en odgovaraju}i broj parametara koji se prosle|uju,
nezavisno od toga koji se parametri koriste u samim funkcijama.

464
Rukovanje sesijama POGLAVLJE 18

Listing 18.2. Rukovalac sesijama, koji koristi podatke iz MySQL baze podataka

<?php

/*
* mysql_session_open()
* Otvara se perzistentna konekcija i selektuje baza podataka.
*/

function mysql_session_open($session_path, $session_name) {

mysql_pconnect("localhost", "sessionmanager", "secret")


or die("Can't connect to MySQL server! ");

mysql_select_db("sessions")
or die("Can't select MySQL sessions database");

} // end mysql_session_open()

/*
* mysql_session_close()
* Nista se, zapravo, ne izvrsava dok je konekcija sa serverom
* perzistentna. Vodite racuna o tome da, iako
* ne radi nista u konkretnoj implementaciji,
* ova funkcija mora biti definisana.
*/

function mysql_session_close() {

return 1;

} // end mysql_session_close()

/*
* mysql_session_select()
* Iz baze podataka ocitavaju se podaci vezani za sesiju
*/

465
PHP i MySQL od po~etnika do profesionalca

function mysql_session_select($SID) {

$query = "SELECT value FROM sessioninfo


WHERE SID = '$SID' AND
expiration > ". time();

$result = mysql_query($query);

if (mysql_num_rows($result)) {

$row=mysql_fetch_assoc($result);
$value = $row['value'];
return $value;

} else {

return "";
}
} // end mysql_session_select()
/*
* mysql_session_write()
* Ova funkcija se koristi za upisivanje podataka, vezanih za sesiju, u bazu podataka.
* If that SID already exists, then the existing data will be updated.
*/

function mysql_session_write($SID, $value) {


// Definisanje vremena trajanja sesije
$lifetime = get_cfg_var("session.gc_maxlifetime");

// Set the session expiration date


$expiration = time() + $lifetime;

466
Rukovanje sesijama POGLAVLJE 18

// Unos podataka, vezanih za sesiju, u bazu podataka


$query = "INSERT INTO sessioninfo
VALUES('$SID', '$expiration', '$value')";

$result = mysql_query($query);

// Ukoliko upit ne da zeljene rezultate, sesija vec postoji.


// Zbog toga je neophodno samo da azurirate sesiju.

if (! $result) {

$query = "UPDATE sessioninfo SET


expiration = '$expiration',
value = '$value' WHERE
SID = '$SID' AND expiration >". time();

$result = mysql_query($query);

}
} // end mysql_session_write()

/*
* mysql_session_destroy()
* Deletes all session information having input SID (only one row)
*/

function mysql_session_destroy($SID) {

// Delete all session information having a particular SID


$query = "DELETE FROM sessioninfo
WHERE SID = '$SID'";

$result = mysql_query($query);

} // end mysql_session_destroy()

467
PHP i MySQL od po~etnika do profesionalca

/*
* mysql_session_garbage_collect()
* Deletes all sessions that have expired.
*/

function mysql_session_garbage_collect($lifetime) {

// Delete all sessions older than a specific age


$query = "DELETE FROM sessioninfo
WHERE sess_expiration < ".time() - $lifetime;

$result = mysql_query($query);

return mysql_affected_rows($result);

} // end mysql_session_garbage_collect()

?>

Nakon {to defini{ete ove funkcije, mo`ete ih povezati u PHP logiku za rukovanje izvr{avanjem
session_set_save_handler() funkcije. Slede}i kod treba da se na|e na kraju biblioteke, koja je
definisana u listingu 18.2:

session_set_save_handler("mysql_session_open", "mysql_session_close",
"mysql_session_select",
"mysql_session_write",
"mysql_session_destroy",
"mysql_session_garbage_collect");

Da biste testirali implementaciju rukovaoca sesijama, startujte sesiju i registrujte promenljivu


sesije kori{}enjem slede}eg skripta:

<?php
INCLUDE "mysqlsessionhandlers.php";
session_start();
$_SESSION['name'] = "Jason";
?>

Nakon izvr{avanja ovog skripta, pogledajte sadr`aj sessioninfo tabele, kori{}enjem mysql
klijenta:

468
Rukovanje sesijama POGLAVLJE 18

+---------------------------------------+-------------------+-------------------
+
| SID | expiration | value |
+---------------------------------------+-------------------+-------------------
+
| f3c57873f2f0654fe7d09e15a0554f08 | 1068488659 | name|s:5:"Jason"; |
+---------------------------------------+-------------------+-------------------
+
1 row in set (0.00 sec)

Kao {to ste i o~ekivali, u tabelu je uba~ena odgovaraju}a vrsta, koja sadr`i identifikator sesije i
promenljivu sesije "Jason". Ova informacija je postavljena tako da istekne 1440 sekundi nakon
kreiranja; ova vrednost se izra~unava utvr|ivanjem trenutnog broja sekundi od po~etka Unix
epohe, i dodavanjem vrednosti 1440 na tu vrednost. Uo~ite da iako je 1440 podrazumevano
vreme za isticanje sesije, kao {to je definisano u php.ini datoteci, ovu vrednost mo`ete sasvim slo-
bodno da promenite nekom vredno{}u koja vam odgovara.

Uo~ite da ovo nije jedini na~in za implementiranje ovih procedura, ukoliko se koristi MySQL
baza podataka. Ovu biblioteku mo`ete i samostalno da modifikujete, onako kako vama
odgovara.

Kratak pregled poglavlja


U ovom poglavlju razmatrane su teme vezane za rukovanje sesijama u programskom jeziku PHP.
Nau~ili ste kako da koristite odgovaraju}e konfiguracione direktive, kako biste definisali `eljeno
funkcionisanje, odnosno kako da koristite neke od najva`nijih funkcija, kojima se mo`e
realizovati rukovanje izuzecima u va{im aplikacijama. Poglavlje je zavr{eno navo|enjem realnih
primera, vezanih za implementiranje rukovaoca izuzecima u programskom jeziku PHP, pri ~emu
je prikazano kori{}enje MySQL tabele za ~uvanje podataka o sesijama.

U narednom poglavlju je opisana jo{ jedna veoma zna~ajna napredna, ali istovremeno i veoma
zna~ajna tema: kori{}enje {ablona. Izdvajanje logike aplikacije od prezentacije je tema o kojoj se
neprekidno puno govori i pi{e, i to s razlogom; ukoliko izme{ate logiku aplikacije i na~in prikazi-
vanja podataka, stvori}ete sebi veliki problem u procesu odr`avanja va{e aplikacije. Do sada je
izdvajanje logike i prezentacije u web aplikacijama bilo veoma retko prakti~no primenjivano. Ali,
to jednostavno mora da se uradi na taj na~in!

469
470

You might also like