Állapotok tárolása munkamenet-függvényekkel

Az elõzõ órában áttekintettük, hogy hogyan lehet süti vagy lekérdezõ karaktersorozat
használatával menteni az oldalak állapotát. A PHP 4 ezeken kívül további lehetõ-
ségeket is nyújt, különbözõ függvényei vannak a felhasználó állapotának mentésére
is. Ezen függvények használata nagyon hasonló az elõzõ órában tanultakhoz, de
mivel közvetlenül a nyelvbe vannak építve, az állapot mentése egyszerû függvényh
ívásokkal végezhetõ el.
Ebben az órában a következõkrõl tanulunk:
• Mik azok a munkamenet-változók és hogyan használhatók?
• Hogyan indítsunk el és folytassunk egy munkamenetet?
• Hogyan tartsuk nyilván a munkamenetek változóit?
• Hogyan semmisítsünk meg egy munkamenetet?
• Hogyan töröljük egy munkamenet egyes változóit?
Mik azok a munkamenet-függvények?
A munkamenet-függvényekkel egyszerûen végezhetjük el azokat a mûveleteket,
amelyekrõl az elõzõ órában tanultunk. Ezek egy különleges felhasználói azonosí-
tót biztosítanak, amellyel oldalról oldalra különbözõ információkat vihetünk át,
hozzákapcsolva azokat ehhez az azonosítóhoz. Az elõzõekhez képest igen nagy
elõny, hogy a függvények használatával kevesebb munka hárul ránk. Amikor
a felhasználó lekér valamilyen munkamenetet támogató oldalt, kap egy azonosí-
tót, vagy a régebbi látogatásakor szerzett meglévõ azonosítója kerül felhasználásra.
Ezt követõen a munkamenethez kapcsolt összes globális változó elérhetõ lesz
a kódban.
A munkamenet-függvények mindkét, az elõzõ órában tanult módszert támogatják.
Alapértelmezés szerint a sütiket használják, ugyanakkor az azonosítókat minden,
a saját oldalunkra mutató kereszthivatkozásban elhelyezhetjük, így biztosítva,
hogy az oldal a sütiket nem támogató böngészõvel is használható legyen.
A munkamenet állapotát a rendszer általában egy ideiglenes fájlban tárolja, de
a megfelelõ modulok használatával az adatokat adatbázisba is tehetjük.
Munkamenet indítása a session_start() függvénnyel
Hacsak nem változtattuk meg a php.ini fájlt, a munkameneteket mindig saját
magunknak kell elindítanunk, alapállapotban azok nem indulnak el automatikusan.
A php.ini fájlban található a következõ sor:
session.auto_start = 0
Változtassuk a session.auto_start értékét 1-re, így a PHP dokumentumokban
a munkamenetek rögtön elindulnak. Ha nem változtatjuk meg az értéket,
mindig meg kell hívnunk a session_start() függvényt.
Miután a munkamenet elindult, a session_id() függvénnyel rögtön hozzáférhet
ünk a felhasználó munkamenet-azonosítójához. A session_id() függvénnyel
lekérdezhetjük vagy módosíthatjuk az azonosítót. A 20.1. példában található program
a munkamenet-azonosítót írja ki a böngészõbe.
382 20. óra
20.1. program Munkamenet indítása vagy folytatása
1: 2: session_start();
3: ?>
4:
5:
6: 20.1. program Munkamenet indítása vagy<br />folytatása
7:
8:
9: 10: print "

Üdvözöljük! Az Ön munkamenet-azonosítója "
.session_id()."

\n\n";
11: ?>
12:
13:
A fenti program elsõ lefutása után létrehoz egy munkamenet-azonosítót.
Ha a felhasználó késõbb újratölti az oldalt, ugyanazt az azonosítót kapja meg.
Ehhez természetesen szükséges, hogy a felhasználó engedélyezze a sütiket
a böngészõjében. Vizsgáljuk meg a 20.1. példa kimenetének fejléceit. A süti
a következõkben lett beállítva:
HTTP/1.1 200 OK
Date: Sun, 07 Jan 2001 13:50:36 GMT
Server: Apache/1.3.9 (Unix) PHP/4.0.3
Set-cookie: PHPSESSID=2638864e9216fee10fcb8a61db382909; path=/
Connection: close
Content-Type: text/html
Mivel a session_start() megpróbálja beállítani a sütit, amikor munkamenetet
hoz létre, el kell indítani, mielõtt bármit kiíratnánk a böngészõvel. Vegyük észre,
hogy nincs lejárati idõ. Ez azt jelenti, hogy a munkamenet csak addig tarthat, amíg
a böngészõ aktív. Amikor a felhasználó leállítja a böngészõt, a sütit nem menti, de
ez a viselkedés a php.ini fájl session.cookie_lifetime beállításának
megváltoztatásával módosítható. Az alapértelmezett beállítás 0, itt kell a lejárati
idõt másodpercben megadni. Ezzel mindegyik munkamenetnek megadjuk
a mûködési határidõt.
Állapotok tárolása munkamenet-függvényekkel 383
20
Munkamenet-változók
A munkamenet-azonosító hozzárendelése a felhasználóhoz csak az elsõ lépés.
Egy munkamenet során tetszõleges számú globális változót vezethetünk be,
amelyeket késõbb bármelyik, a munkameneteket támogató oldalunkról elérhetünk.
A változó bejegyzéséhez, bevezetéséhez a session_register() függvényt kell
használnunk. A session_register() függvény paramétereiben karaktersorozatokat
kell megadni, így határozva meg egy vagy több bevezetendõ változó nevét.
A függvény visszatérési értéke true, ha a bejegyzés sikeres volt. A függvény param
étereiben csak a változók nevét kell megadni, nem pedig a változók értékeit.
A 20.2. példában két változó bejegyzését láthatjuk.
20.2. program Változók bejegyzése
1: 2: session_start();
3: ?>
4:
5:
6: 20.2. program Változók bejegyzése
7:
8:
9: 10: session_register( "termek1" );
11: session_register( "termek2" );
12: $termek1 = "Ultrahangos csavarhúzó";
13: $termek2 = "HAL 2000";
14: print session_encode();
15: print "A változókat bejegyeztük";
16: ?>
17:
18:
A 20.2. példában látható kódnak nincs túl sok értelme, amíg a felhasználó be nem
tölt egy új oldalt. A 20.3. példában egy olyan PHP program látható, amely a 20.2.
példában bejegyzett változókat használja.
384 20. óra
20.3. program Bejegyzett változók használata
1: 2: session_start();
3: ?>
4:
5:
6: 20.3. program Bejegyzett változók<br />használata
7:
8:
9: 10: print "Az Ön által kiválasztott termékek:\n\n";
11: print "
  • $termek1\n
  • $termek2\n
\n";
12: ?>
13:
14:
A 20.3. program eredménye a 20.1. ábrán látható. Látjuk, hogy az oldalról hozzáfé-
rünk a másik programban bejegyzett $termek1 és $termek2 változókhoz.
Hogyan mûködik mindez? A PHP 4 a háttérben folyamatosan fenntart egy ideiglenes
fájlt a munkamenet számára. A session_save_path() függvény használat
ával e fájl elérési útját deríthetjük ki, de a függvénynek egy könyvtár elérési útját
is megadhatjuk. Ha ezt meghatározzuk, az ideiglenes munkamenet-fájlok ezután
Állapotok tárolása munkamenet-függvényekkel 385
20
20.1. ábra
Bejegyzett változók
használata
ide kerülnek. Ha a függvényt paraméter nélkül futtatjuk, visszatérési értéke annak
a könyvtárnak az elérési útja lesz, ahová a rendszer az ideiglenes munkamenetf
ájlokat menti. A szerzõ rendszerén a
print session_save_path();
visszatérési értéke /tmp. A /tmp könyvtár például a következõ fájlokat tartalmazhatja:
sess_2638864e9216fee10fcb8a61db382909
sess_76cae8ac1231b11afa2c69935c11dd95
sess_bb50771a769c605ab77424d59c784ea0
Amikor megnyitjuk azt a fájlt, melynek neve a 20.1. példában visszaadott munkamenet-
azonosítót tartalmazza, láthatjuk, hogyan tárolódnak a bejegyzett változók:
termek1|s:22:"Ultrahangos csavarhúzó";termek2|s:8:"HAL 2000";
Amikor meghívjuk a session_register() függvényt, a PHP beírja a fájlba
a változó nevét és értékét. Késõbb innen kapjuk meg a változó értékét.
Ha a session_register() függvénnyel bejegyeztünk egy változót, annak
a PHP program futása során módosított értéke a munkamenet-fájlban is
meg fog változni.
A 20.2. példa bemutatta a session_register() függvény használatát, de
a függvény mûködése nem tûnik túl rugalmasnak. Mit tehetünk, ha a felhasználó
többféle terméket tartalmazó változókat szeretne bevezetni? Szerencsére
a session_register() függvény paraméterében tömb típusú változót is
megadhatunk.
A 20.4. példában a felhasználó több termék közül választhat. Ezután munkamenetv
áltozókkal létrehozunk egy egyszerû „bevásárlókosarat”.
20.4. program Tömb típusú változó bejegyzése
1: 2: session_start();
3: ?>
4:
5:
6: 20.4. program Tömb típusú változó<br />bejegyzése
7:
386 20. óra
20.4. program (folytatás)
8:
9:

Termékböngészõ lap


10: 11: if ( isset( $termekek_urlap ) )
12: {
13: $termekek = $termekek_urlap;
14: session_register( "termekek" );
15: print "

A termékeit bejegyeztük!

;
16: }
17: ?>


18:


19:
26:


27:
28:


29:


30: Tartalom
31:
32:
Elõször elindítjuk a munkamenetet a session_start() függvénnyel. Ezzel
hozzáférünk minden korábban beállított munkamenet-változóhoz. A HTML dokumentumon
belül a FORM elem ACTION tulajdonságát beállítjuk a jelenlegi dokumentumra.
Létrehozunk egy termekek_urlap[] nevû SELECT elemet, amely
a termékek számával megegyezõ OPTION összetevõt tartalmaz. Emlékezzünk rá,
hogy a HTML dokumentum azon elemeinek, amelyek engedélyezik több elem
kiválasztását, szögletes zárójellel együtt kell megadni a NAME paraméterét.
Így a felhasználó választása egy tömbbe kerül.
A PHP kód blokkjában megvizsgáljuk, hogy létezik-e a $termekek_urlap tömb.
Ha a változó létezik, feltehetjük, hogy a kérdõívet kitöltötték. Ezt a változót hozzá-
rendeljük a $termekek változóhoz, amit a session_register() függvénnyel
bejegyzünk. A $termekek_urlap tömböt közvetlenül nem jegyezzük be, mert
ez egy késõbbi kitöltés során ütközést okozhat az ugyanilyen nevû, POST eljárással
érkezett változóval.
Állapotok tárolása munkamenet-függvényekkel 387
20
A kód végén megadunk egy hivatkozást, ahol bemutatjuk, hogy valóban hozzáfé-
rünk a bejegyzett tömbhöz. Ez a kód a 20.5. példában található.
20.5. program Hozzáférés bejegyzett tömb típusú változóhoz
1: 2: session_start();
3: print session_encode(); //kódolt karaktersorozat kiírása
4: ?>
5:
6:
7: 20.5. program Hozzáférés bejegyzett<br />tömb típusú változóhoz
8:
9:
10:

Tartalom lap


11: 12: if ( isset( $termekek ) )
13: {
14: print "A bevásárlókocsi tartalma:
    \n";
    15: foreach ( $termekek as $egytermek )
    16: print "
  1. $egytermek";
    17: print "
";
18: }
19: ?>
20: Vissza
a termékválasztáshoz

21:
22:
A session_start() használatával folytatjuk a munkamenetet. Ellenõrizzük, hogy
létezik-e a $termekek változó. Ha létezik, elemeit egyenként kiírjuk a böngészõbe.
Természetesen egy igazi „bevásárlókosár-program” megírásakor a termékeket
érdemes adatbázisban, és nem a futtatandó kódban tárolni. A 20.4. és 20.5. példa
csak azt mutatta be, hogyan érhetõ el egy tömb típusú változó egy másik oldalról.
388 20. óra
A munkamenet és a változók bejegyzésének törlése
A munkameneteket és a bejegyzett változókat a session_destroy() függv
énnyel törölhetjük. A session_destroy() függvénynek nincsenek paraméterei,
futtatásához azonban szükséges egy folyamatban lévõ munkamenet. A következõ
kódrészlet létrehoz, majd rögtön megsemmisít egy munkamenetet:
session_start();
session_destroy();
Amikor olyan oldalt töltünk be, amely egy munkamenetet vár, az már nem látja
a korábban törölt munkamenetet, ezért létre kell hoznia egy újat. Minden korábban
bejegyzett változó elvész.
Valójában a session_destroy() függvény nem semmisíti meg a bejegyzett változ
ókat. Abban a kódban, amelyben a session_destroy() függvényt futtattuk,
a változók továbbra is elérhetõk. A következõ kódrészletben látható, hogy az 5-re
állított $proba változó a session_destroy() meghívása után is elérhetõ marad.
A munkamenet megszüntetése nem törli a bejegyzett változókat.
session_start();
session_register( "proba" );
$proba = 5;
session_destroy();
print $proba; // kiírja, hogy 5
A munkamenetbõl a bejegyzett változókat a session_unset() függvénnyel
távolíthatjuk el. A session_unset() a munkamenet-fájlból és a programból is
eltávolítja a változókat, ezért óvatosan használjuk.
session_start();
session_register( “proba” );
$proba = 5;
session_unset();
session_destroy();
print $proba; // nem ír ki semmit. a $proba változó
å már nem létezik.
A munkamenet megszüntetése elõtt meghívjuk a session_unset() függvényt,
amely eltávolítja a $proba, és minden más bejegyzett változót a memóriából.
Állapotok tárolása munkamenet-függvényekkel 389
20
Munkamenet-azonosítók a lekérdezõ karakterláncban
Áttekintettük a sütin alapuló munkamenetek kezelését. Tudnunk kell azonban,
hogy ez nem a legbiztosabb módszer. Nem feltételezhetjük ugyanis, hogy a látogat
ó böngészõje támogatja a sütik használatát. A probléma elkerülése végett építs
ünk be programunkba egy, a munkamenet-azonosító továbbadására alkalmas
lekérdezõ karakterláncot. A PHP létrehozza a SID állandót, ha a böngészõ nem
küldött vissza azonosítót tartalmazó sütit. A SID név–érték alakú állandó karakterl
ánc, amelyet beágyazhatunk a munkamenetet támogató oldalra mutató HTML
hivatkozásokba:
Másik lap
A böngészõben ez már így jelenik meg:
Másik lap
A munkamenet-azonosító automatikusan átvételre kerül, amikor a céloldalon
meghívjuk a session_start() függvényt, és az összes korábban bejegyzett
változó a szokásos módon elérhetõ lesz.
Ha a PHP 4-et az --enable-trans-sid kapcsolóval fordítottuk le a fenti lekérdez
õ karakterlánc automatikusan hozzáadódik minden HTML hivatkozáshoz.
Ez a lehetõség alapállapotban kikapcsolt, de használatával kódjaink hordozhat
óbbá válnak.
Munkamenet-változók kódolása és visszafejtése
Amikor megnéztük a munkamenet-fájl tartalmát, láttuk, hogyan menti és kódolja
a PHP a bejegyzett változókat. A kódolt karaktersorozathoz a session_encode()
függvény használatával bármikor hozzáférhetünk. Ez hasznos lehet a munkamenetek
nyomkövetésénél. A következõ kódrészletben láthatjuk, hogyan mûködik
a session_encode() függvény.
session_start();
print session_encode()."
";
// minta eredmény: termekek|a:2:{i:0;s:8:
å "HAL 2000";i:1;s:8:"Targonca";}
Látható, hogy a függvény tárolási alakjukban adja vissza a bejegyzett változókat, így
ellenõrizhetjük, hogy a változó valóban be lett-e jegyezve és értéke megfelelõ-e.
A session_encode() függvény használatával bejegyzett változókat tartalmazó
adatbázisokat is készíthetünk.
390 20. óra
A session_decode() függvény használatával a változók kódolt formájából
visszanyerhetjük az értéküket. A következõ kódrészlet ezt mutatja be:
session_start();
session_unset(); // nem szabad, hogy létezzenek
å munkamenet-változók
session_decode( "termekek|a:2:{i:0;s:8:\”HAL 2000\";
å i:1;s:8:\"Targonca\";}" );
foreach ( $termekek as $egytermek )
{
print "$egytermek
\n";
}
// Kimenet:
// HAL 2000
// Targonca
A szokásos módon elindítjuk a munkamenetet. Hogy tiszta lappal induljunk,
a session_unset() függvénnyel töröljük az összes korábban bejegyzett változót.
Ezután átadjuk a session_decode() függvénynek a változók kódolt formáját.
A függvény párosítja a változóneveket a megfelelõ értékekkel. Ezt ellenõrizzük is:
a $termekek tömb minden elemét kiíratjuk.
Munkamenet-változó bejegyzésének ellenõrzése
Mint láttuk, a bejegyzett változó jelenlétét az isset() függvénnyel ellenõrizhetj
ük, de más módon is megvizsgálhatjuk a változó létezését. Erre való
a session_is_registered() függvény. A függvény paraméterében egy változó
nevét tartalmazó karakterláncot kell megadni, a visszatérési érték pedig true,
ha a változó bejegyzett.
if ( session_is_registered ( "termekek" ) )
print "A 'termekek' változó bejegyzett!";
Ez akkor lehet hasznos, ha biztosak akarunk lenni a változó forrásában, azaz, hogy
a változó tényleg a munkamenet bejegyzett változója vagy csak egy GET kérelem
eredményeként kaptuk.
Állapotok tárolása munkamenet-függvényekkel 391
20
Összefoglalás
Ebben és az elõzõ órában áttekintettük, hogyan menthetjük az állapotokat
egy állapot nélküli protokollban. Különféle módszereket alkalmaztunk: sütiket és
lekérdezõ karakterláncokat használtunk, néha ezeket fájlokkal és adatbázisokkal
ötvöztük. Mindegyik megközelítési módnak megvannak a maga elõnyei és
hátrányai.
A süti nem igazán megbízható és nem tárolhat sok információt. Ezzel szemben
hosszú ideig fennmaradhat.
Az adatok fájlban vagy adatbázisban való tárolása miatt a sebesség csökkenhet,
ami gondot okoz egy népszerû webhelyen. Ugyanakkor egy egyszerû azonosí-
tóval nagy mennyiségû adathoz férhetünk hozzá.
A lekérdezõ karakterlánc a süti ellentéte. Elég csúnyán néz ki, de viszonylag nagy
mennyiségû információt hordoz magában. Használatáról a körülmények mérlegel
ése után kell dönteni.
Ebben az órában megtanultuk, hogyan indítsunk el munkamenetet
a session_start() függvénnyel. Láttuk, hogyan jegyezhetünk be változókat
a session_register() függvénnyel, hogyan ellenõrizhetjük a bejegyzést
a session_is_registered() függvénnyel, valamint hogyan semmisíthetjük
meg a változókat a session_unset() függvénnyel. A munkamenet megsemmis
ítésére a session_destroy() függvényt használtuk.
Hogy minél több felhasználó érhesse el a munkamenetet támogató környezetet,
lekérdezõ karakterláncainkban használjuk a SID állandót a munkamenet-azonos
ító átadására.
Kérdések és válaszok
Van valamilyen veszélye a munkamenet-függvények használatának,
amirõl még nem tudunk?
A munkamenet-függvények alapvetõen megbízhatók. De emlékezzünk rá, hogy
a sütik használata nem lehetséges több tartományon keresztül. Ezért, ha több tartom
ánynevet használunk ugyanazon a kiszolgálón (elektronikus kereskedelemi alkalmaz
ásoknál ez gyakori), tiltsuk le a sütik használatát a session.use_cookies 0-
ra állításával a php.ini fájlban.
392 20. óra
Mûhely
A mûhelyben kvízkérdések találhatók, melyek segítenek megszilárdítani az órában
szerzett tudást. A válaszokat az A függelékben helyeztük el.
Kvíz
1. Melyik függvényt használjuk egy munkamenet elindítására?
2. Melyik függvény adja vissza a jelenlegi munkamenet azonosítóját?
3. Hogyan rendelhetünk változókat a munkamenethez?
4. Hogyan semmisíthetjük meg a munkamenetet és törölhetjük el minden nyomát?
5. Hogyan semmisíthetjük meg az összes munkamenet-változót a futó programban
és az egész munkamenetben?
6. Mi a SID állandó értéke?
7. Hogyan ellenõrizhetjük, hogy a $proba nevû változó be van-e jegyezve
egy munkameneten belül?
Feladatok
1. Az elõzõ óra Feladatok részében készítettünk egy programot, amely sütit
vagy lekérdezõ karakterláncot használ, hogy oldalról oldalra vigye tovább
a felhasználó válaszait. Ezután a környezet minden oldala a beállított háttérsz
ínnel indult és név szerint üdvözölte a felhasználót. Készítsük el ezt a programot
a PHP 4 munkamenet-függvényeivel.
2. Készítsünk programot, amely munkamenet-függvények használatával emlé-
kezik rá, hogy a felhasználó a környezet mely oldalait látogatta meg. Készítsük
el a felhasználó lépéseit tartalmazó hivatkozások sorozatát, hogy mozgása
nyomon követhetõ legyen.