Teljes példa (elsõ rész)

Ha figyelmesen követtük az egyes órák anyagát, jó alapokkal rendelkezünk a PHP
programozáshoz. Ebben és a következõ órában egy teljes, mûködõ programot
készítünk, amely az elõzõ órákban tárgyalt eljárásokból építkezik.
Az órában a következõket tanuljuk meg:
• Hogyan készítsünk tervet?
• Hogyan használjuk az include() nyelvi szerkezetet, hogy függvénykönyvt
árakat és újrahasznosítható navigációs elemeket készítsünk?
• Hogyan tartsuk nyilván az állapotokat GET típusú lekérdezésekkel, adatbá-
zisokkal és munkamenet-függvényekkel?
• Hogyan válasszuk el a HTML és a PHP kódot, hogy a programozásban
járatlan grafikus is dolgozhasson az oldalon?
• Hogyan védjük meg szolgáltatásunk oldalait felhasználó-azonosítással?
A feladat rövid leírása
Tegyük fel, hogy egy közösségi webhely tulajdonosai felkértek bennünket, hogy
készítsünk el egy kis interaktív eseménynaptárt az általuk kiszolgált kisváros
számára. Klubok és együttesek jegyeztethetik be magukat, hogy reklámozzák
rendezvényeiket. A webhely felhasználói ezután különbözõ formákban kiírathatj
ák majd az adatbázist, hogy lássák, milyen rendezvények lesznek a városban.
A felhasználók képesek lesznek a lista szûkítésére a klubok típusa vagy akár
a szervezett rendezvény helye szerint is.
Az oldalak felépítése
Mielõtt akár egy sor kódot is írnánk, el kell döntenünk, hogyan fog mûködni
programunk. Milyen módon fogják elérni a felhasználók a rendszer különbözõ
elemeit? Milyen oldalakra van szükségünk?
A program természetesen két részre tagolódik. Az elsõ a tagok számára kialakított
terület, amely a klubok információinak kezelésére, új események hozzáadására
szolgál majd. A második a felhasználók területe, ahol az adatbázison lekérdezéseket
kell majd végrehajtani.
A 23.1. ábra az alkalmazás felépítését mutatja.
430 23. óra
A továbbiakban tagoknak nevezzük azokat a személyeket,
akik klubjukat bejegyezve felügyeleti feladatokat látnak el, és
felhasználóknak azokat az érdeklõdõket, akik a listákat böngészve
barangolnak a klubok és események között.
23.1. ábra
Az alkalmazás
felépítése
Az új tagok a csatlakozas.php oldalon csatlakozhatnak a rendszerhez (itt jegyeztethetik
be magukat a tagok közé), egy név–jelszó pár megadásával. Ha a vá-
lasztott név még nem foglalt, a leendõ tag a klubfrissites.php oldalra kerül,
ahol egy ûrlapon meg kell adnia a klubról a szükséges információkat. Amíg ki
nem tölti ezt az ûrlapot, nem vihet be új rendezvényeket a rendszerbe. Ha a tag
a hozzá tartozó klub adatait sikeresen bevitte, a tagok menüjéhez kerül
(tagmenu.php), ahonnan a tagok részére készített valamennyi oldal elérhetõ.
A már bejegyzett tagok a belépõ oldalról indulnak (belepes.php). Ha a megadott
név és jelszó helyesnek bizonyult, egyenesen a tagmenu.php oldalra kerülnek.
A menü oldalról indulva a tagok új rendezvényeket adhatnak a rendszerhez
(esemenyfrissites.php) és megtekinthetik az adatbázisban levõ rendezvé-
nyeik listáját (esemenylista.php). A klub adatait a klubfrissites.php
oldalon bármikor módosíthatják.
Minden felhasználó képes lesz az események hónapok, napok, típusok és terü-
letek alapján történõ rendezett kiíratására, egyetlen PHP oldal segítségével
(esemenyekinfo.php). Lehetõség lesz a klubok felsoroltatására is, terület vagy
típus alapján (klubokinfo.php). Végül a felhasználók egy klubra vagy
eseményre kattintva bõvebb információkat tudhatnak meg (esemenyinfo.php,
klubinfo.php).
Az adatbázis kialakítása
Az alkalmazás adatainak tárolásához létre kell hoznunk a szervezo adatbázist és
ebben négy táblát: klubok, esemenyek, teruletek, tipusok. Nyilvánvaló,
hogy a klubok és rendezvények adatait külön táblákban kell tárolnunk, hiszen
egy klubhoz több rendezvény is tartozhat. A területek és típusok számára kialak
ított táblák jelentõsen megkönnyítik a listázáshoz és adatbevitelhez szükséges
lenyíló menük kialakítását. A táblákat SQL parancsokkal hozzuk létre, „kézi úton”.
A klubok tábla a következõképpen hozható létre:
CREATE TABLE klubok (
azonosito INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
klubnev VARCHAR(50),
tipus CHAR(3),
terulet CHAR(3),
email VARCHAR(50),
ismerteto BLOB,
nev VARCHAR(8),
jelszo VARCHAR(8)
);
Teljes példa (elsõ rész) 431
23
A tagok a klubnev, email, ismerteto, nev és jelszo mezõk adatait fogják
megadni. A tipus és terulet mezõk értelemszerûen a tipusok és
teruletek megfelelõ soraira vonatkozó azonosítókat tartalmazzák majd.
Az esemenyek tábla az eseményekre vonatkozó valamennyi információt
tartalmazza:
CREATE TABLE esemenyek (
eazonosito INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
etipus CHAR(3),
eterulet CHAR(3),
edatum INT,
enev VARCHAR(100),
ehelyszin VARCHAR(100),
ecim VARCHAR(255),
eirsz CHAR(4),
eismerteto BLOB,
eklub INT NOT NULL
);
Vegyük észre, hogy ez a tábla is tartalmaz etipus és eterulet mezõket, hiszen
elõfordulhat, hogy egy klub a város északi részén található, de valamelyik rendezv
ényét a déli városrészben tartja. Egy társadalmi csoport tarthat oktatási szemináriumot,
de politikai találkozót is. Az eklub mezõ annak a klubnak az azonositó-
számát tartalmazza, amelyik az adott esemény szervezõje. A kapcsolat arra
használható fel, hogy egy klub összes rendezvényét felsoroljuk, illetve hogy elérj
ük az eseményhez köthetõ klub adatait.
A teruletek és tipusok táblák igen egyszerûek:
CREATE TABLE teruletek ( azonosito CHAR(3),
å terulet VARCHAR(30));
CREATE TABLE tipusok ( azonosito CHAR(3),
å tipus VARCHAR(30));
A tagok számára nem adunk lehetõséget ezen táblák módosítására, inkább elõre
meghatározott csoportokat alakítunk ki, melyeket INSERT SQL parancsokkal
adunk a táblákhoz. A tagok ezekbõl a listákból választhatnak majd.
INSERT INTO tipusok (azonosito, tipus) VALUES
å ("CSA", "Családi");
A 23.1. és 23.2. táblázatban az említett táblákba illesztendõ adatok láthatók.
432 23. óra
23.1. táblázat A teruletek táblához adott adatok
azonosito terulet
ESZ Észak
DEL Dél
KEL Kelet
NYU Nyugat
23.2. táblázat A tipusok táblához adott adatok
azonosito tipus
ZEN Zenei
CSA Családi
TRS Társadalmi
KZS Közösségi
Tervezési döntésünk
Az elõzõ bekezdésekben már láttuk, milyen szerkezetû alkalmazást készítünk.
Úgy döntöttünk, hogy a különbözõ szolgáltatásokhoz különbözõ PHP programokat
készítünk, ahelyett, hogy egyetlen hatalmas programot építenénk fel, amely a körülm
ényeknek megfelelõen más-más oldalakat szolgáltat. Ennek a döntésnek termé-
szetesen vannak elõnyei és hátrányai is.
Ha egy ilyen dinamikus környezetet több oldalból építünk fel, a kódok ismétlésének
hibájába eshetünk és a program növekedésével megnehezíthetjük a fejlesztõk dolgát.
Másrészt viszont a befejezett prototípust átadhatjuk grafikusainknak, akik majdnem
úgy kezelhetik azt, mintha pusztán HTML kódot tartalmazna.
A tagoknak szánt oldalak
Most már itt az ideje, hogy megkezdjük a kód írását. Az óra további részében
az alkalmazás tagoknak szánt oldalait készítjük el. Jó ötlet ezekkel kezdeni, mivel
így könnyebben vihetünk be próbaadatokat a rendszerbe. Mielõtt azonban
az adatbevitelt megkezdhetnénk, képesnek kell lennünk a tagok felvételére.
Teljes példa (elsõ rész) 433
23
csatlakozas.php és adatbazis.inc
A csatlakozas.php tartalmazza azt az ûrlapot, amelyen keresztül az új tagok
egy név és jelszó segítségével bejegyeztethetik klubjukat a rendszerbe. Ahhoz, hogy
felvehessük az adatokat és kiszûrhessük az ismétlõdéseket, elõször meg kell
nyitnunk egy kapcsolatot az adatbázis felé. Ez az ilyen alkalmazásoknak annyira
jellemzõ eleme, hogy célszerû külön függvényt készíteni erre a célra, melyet jelen
esetben egy külsõ állományban fogunk tárolni. Ezt a külsõ fájlt késõbb minden
oldalon az include() nyelvi elemmel illesztjük a kódba. Tulajdonképpen minden
adatbázissal kapcsolatos függvényt ebben tárolunk majd, ezért az adatbazis.inc
nevet kapja, szerepe és a beillesztés módja után. Ezzel a fájllal a további PHP oldalakat
mindennemû SQL parancstól mentesítjük.
Az adatbázissal kapcsolatot tartó kódok külön fájlba helyezése könnyebbé teszi
a program késõbbi módosítását vagy más adatbázismotorra való átültetését.
Elõfordulhat, hogy késõbb újra kell írnunk a függvényeket, de a hívó kódok
módosítására nem lesz szükség.
Hozzuk létre a függvényt, amely végrehajtja a csatlakozást:
23.1. program Részlet az adatbazis.inc fájlból
1: $kapcsolat;
2: dbCsatlakozas();
3: function dbCsatlakozas()
4: {
5: global $kapcsolat;
6: $kapcsolat = mysql_connect( "localhost",
"felhasznalo", "jelszo" );
7: if ( ! $kapcsolat )
8: die( "Nem lehet csatlakozni a MySQL-hez" );
9: mysql_select_db( "szervezo", $kapcsolat )
10: or die ( "Nem lehet megnyitni az adatbázist:
".mysql_error() );
11: }
A dbCsatlakozas() függvény a $kapcsolat globális változót használja arra,
hogy a mysql_connect() által visszaadott kapcsolatazonosítót tárolja. Mivel
a változó globális, a többi adatbázisfüggvény is elérheti. Nem csupán a MySQL
kiszolgálóhoz csatlakozunk ebben a függvényben, hanem megpróbáljuk kivá-
lasztani a szervezo adatbázist is. Mivel ezen mûveletek sikere döntõ fontosságú
a teljes alkalmazás mûködése szempontjából, a mysql_connect() vagy
mysql_select_db() végrehajtásának kudarca esetén befejezzük a program
futását.
434 23. óra
A munkamenetek követése és az azonosítással kapcsolatos feladatokat ellátó függv
ények számára egy újabb külsõ állományt használunk. A munkamenet-függvényeket
arra használjuk, hogy egy $munkamenet nevû asszociatív tömböt õrizzünk
meg kérésrõl kérésre. A kozosfv.inc állomány session_start() függvénye
arra szolgál, hogy megkezdjünk vagy folytassunk egy munkamenetet, a változónkat
pedig a session_register() függvénnyel rendeljük ehhez:
23.2. program Részlet a kozosfv.inc fájlból
1: session_start();
2: session_register( "munkamenet" );
Emlékezzünk rá, hogy minden PHP kód, amit ezen külsõ fájlokba írunk, PHP blokk
kezdõ () elemek között kell, hogy legyen. Értelmetlen bonyolí-
tásnak tûnhet, hogy a különbözõ szolgáltatásokat külsõ állományokba helyezzük,
de ez rengeteg kódismétléstõl kímél majd meg bennünket, amikor oldalainkat elké-
szítjük. Most már készen állunk a csatlakozas.php oldal megírására.
23.3. program csatlakozas.php
1: 2: include("adatbazis.inc");
3: include("kozosfv.inc");
4:
5: $uzenet="";
6:
7: if ( isset( $mitkelltenni ) &&
$mitkelltenni=="csatlakozas")
8: {
9: if ( empty( $urlap["nev"] ) ||
10: empty( $urlap["jelszo"] ) ||
11: empty( $urlap["jelszo2"] ) )
12: $uzenet .= "Ki kell töltenie minden
mezõt!
\n";
13:
14: if ( $urlap["jelszo"] != $urlap["jelszo2"] )
15: $uzenet .= "A jelszavak nem
egyeznek!
\n";
16:
Teljes példa (elsõ rész) 435
23
23.3. program (folytatás)
17: if ( strlen( $urlap["jelszo"] ) > 8 )
18: $uzenet .= "A jelszó hossza legfeljebb
19: 8 karakter lehet!
\n";
20:
21: if ( strlen( $urlap["nev"] ) > 8 )
22: $uzenet .= "A tagsági név hossza
legfeljebb
23: 8 karakter lehet!
\n";
24:
25: if ( sorLekeres( "klubok", "nev",
$urlap["nev"] ) )
26: $uzenet .= "A megadott tagsági néven.\""
$urlap["nev"] ."\"
27: már van bejegyzett tagunk.
28: Kérjük, adjon meg más
nevet!
\n";
29:
30: if ( $uzenet == "" ) // nem találtunk hibát
31: {
32: $azon = ujTag( $urlap["nev"],
$urlap["jelszo"] );
33: munkamenetFeltoltes( $azon, $urlap["nev"],
$urlap["jelszo"] );
34:
35: header( "Location:
klubfrissites.php?".SID );
36: exit;
37: }
38: }
39: ?>
40:
41:
42:
43: Csatlakozás
44:
45:
46:
47: 48: include("kozosnav.inc");
49: ?>
50:


51:

Csatlakozás


436 23. óra
23.3. program (folytatás)
52:
53: 54: if ( $uzenet != "" )
55: {
56: print "$uzenet

";
57: }
58: ?>
59:
60:


61:


62: value="csatlakozas">
63: 64: value="">
65: Tagsági név:

66: 67: value=""
maxlength=8>
68:


69:


70: Jelszó:

71: value="" maxlength=8>
72:


73:


74: Jelszó megerõsítés:

75: value="" maxlength=8>
76:


77:


78:
79:


80:

81:
82:
83:
Elõször az include() használatával beillesztjük a külsõ állományokat, tehát
azonnal rendelkezésünkre áll egy adatbáziskapcsolat és egy aktív munkamenet.
Létrehozunk egy $uzenet nevû változót. Ezzel a kettõs célú változóval még
Teljes példa (elsõ rész) 437
23
számos más oldalon találkozni fogunk. Az $uzenet célja egyrészt, hogy tartalmazza
a hibaüzenetet, amit késõbb kiírhatunk a böngészõ számára, másrészt haszn
álhatjuk feltételes kifejezésekben, hogy ellenõrizzük, volt-e hibaüzenet vagy sem.
Ha a változó üres marad, feltételezhetjük, hogy minden ellenõrzés sikeresen
végrehajtódott.
Ezután a $mitkelltenni változó létezését és tartalmát vizsgáljuk. Ez is olyan
elem, amely többször felbukkan majd az alkalmazásban. Minden általunk készített
ûrlapon beállítunk egy mitkelltenni nevû rejtett elemet és egy, az adott szolgáltat
ásra vonatkozó értéket adunk neki. Ha PHP programunkban a $mitkelltenni
változó létezik és a várt érték található benne, biztosak lehetünk abban, hogy az ûrlapot
kitöltötte valaki, így folytathatjuk a programot az ûrlap adatainak ellenõrzésé-
vel. Ha a változó nem létezik, tudhatjuk, hogy a látogató egy hivatkozáson keresztül
vagy a böngészõjében lévõ könyvjelzõ révén érkezett az oldalra és nem töltötte ki
az ûrlapot.
Egyelõre ugorjunk a HTML rész tárgyalására. A body HTML elemen belül elõször
egy újabb külsõ fájlt illesztünk be, amely a különbözõ oldalakra mutató hivatkozá-
sokat tartalmazza. Célszerû már a kezdetektõl beilleszteni a navigációs sávot, mivel
ez megkönnyíti az alkalmazás ellenõrzését, ahogy folyamatosan fejlesztjük azt.
A navigációs elemeket a kozosnav.inc nevû állományban helyezzük el.
Egyelõre ez a fájl csak a látogatók számára is elérhetõ oldalakra mutató hivatkoz
ásokat tartalmazza.
23.4. program Részlet a kozosnav.inc fájlból
1:


2: Klubinformációk |
3: Eseményinformációk |
4: Csatlakozás |
5: Belépés |
6: Honlap
7:


Azzal, hogy a navigációs elemeket külön állományba helyezzük, egyetlen mozdulattal
módosíthatjuk a hivatkozásokat, illetve az elemek kinézetét a teljes alkalmaz
ásra vonatkozóan.
438 23. óra
Visszatérve a csatlakozas.php oldalra, miután kiírjuk az oldal címsorát, ellen-
õrizzük az $uzenet változót. Ha nem üres, kiírjuk a tartalmát a böngészõ számára.
Az összegyûjtött hibaüzenetek kiírásával jelezhetjük a tagnak, hogy a bevitt adatok
nem dolgozhatók fel.
A HTML ûrlap elemei között három látható mezõt hoztunk létre, az urlap[nev],
urlap[jelszo] és urlap[jelszo2] mezõket. Azért használjuk ezeket
az elsõre esetleg furcsának látszó elnevezéseket, mert a PHP az így megadott
nevekkel érkezõ értékeket egy asszociatív tömbbe rendezi, amit $urlap néven
érhetünk majd el. Ez megóv bennünket attól, hogy a globális változók környezetét
„beszennyezzük”, azaz feleslegesen sok globális változót hozzunk létre. Programjainkban
így minden munkamenet-érték a $munkamenet asszociatív tömbben,
az ûrlapértékek pedig az $urlap asszociatív tömbben érhetõk el. Ez megvéd
bennünket a változók ütközésétõl. Célszerû a lehetõ legkevesebbre csökkenteni
a globális változók számát egy ilyen méretû programban, hogy megelõzzük
a kavarodást. A továbbiakban minden ûrlapot tartalmazó oldalon az $urlap
tömbbel fogunk találkozni.
Az ûrlapban létrehozzuk a már korábban említett mitkelltenni rejtett elemet is,
valamint egy másikat, amely a munkamenet nevét és értékét tartalmazza majd.
Az alkalmazás elkészítése során mindig oldalról-oldalra fogjuk adni a munkamenetazonos
ítót, mivel nem kívánjuk elveszteni azokat a látogatókat, akik nem tudnak
vagy nem akarnak sütiket fogadni.
Most, hogy megnéztük a HTML ûrlapot, rátérhetünk arra a kódra, amely a bemenõ
adatok ellenõrzését végzi. Elõször meg kell bizonyosodnunk róla, hogy a leendõ
tag valóban kitöltötte-e az összes mezõt és hogy egyik mezõ hossza sem haladja
meg a nyolc karaktert. Ezután meghívjuk az új sorLekeres() függvényt.
Ez azon függvények egyike, amelyek az adatbazis.inc fájlban találhatók.
Elsõ paramétere egy táblanév, a második egy mezõnév, a harmadik egy érték.
Ezen adatok alapján a függvény egy illeszkedõ sort keres az adatbázisban,
visszaadva azt egy tömbben.
Teljes példa (elsõ rész) 439
23
Ha munkameneteket használó programokat ellenõrzünk,
célszerû kikapcsolni a böngészõben a sütik elfogadását.
Így pontosan tudni fogjuk, hogy a munkamenet azonosítóját
sikeresen át tudjuk-e adni oldalról oldalra ezen szolgáltatás
nélkül is vagy sem.
23.5. program Részlet az adatbazis.inc fájlból
1: function sorLekeres( $tabla, $mezonev, $mezoertek )
2: {
3: global $kapcsolat;
4: $eredmeny = mysql_query( "SELECT * FROM $tabla
WHERE $mezonev='$mezoertek'",
$kapcsolat );
5: if ( ! $eredmeny )
6: die ( "sorLekeres hiba: ".mysql_error() );
7: return mysql_fetch_array( $eredmeny );
8: }
A függvénynek a klubok táblanevet, a nev mezõnevet és a látogatók által bevitt
$urlap["nev"] mezõértéket adjuk át. Ha a mysql_fetch_array() nem
üres tömböt ad vissza, tudhatjuk, hogy egy ilyen belépési névvel rendelkezõ tag
már van a rendszerben, ezért hibaüzenetet kell adnunk.
Ha az ellenõrzések után az $uzenet változó még mindig üres, létrehozhatjuk
az új tagot a bevitt adatokkal. Ez két lépésbõl tevõdik össze. Elõször is frissíteni kell
az adatbázist. Ehhez egy új függvény tartozik az adatbazis.inc állományból,
ujTag() néven:
23.6. program Részlet az adatbazis.inc fájlból
1: function ujTag( $nev, $jelszo )
2: {
3: global $kapcsolat;
4: $eredmeny = mysql_query( "INSERT INTO klubok
(nev, jelszo)
5: VALUES('$nev', '$jelszo')",
$kapcsolat);
6: return mysql_insert_id( $kapcsolat );
7: }
A függvény egy név és egy jelszó paramétert vár, majd ezeket új sorként felveszi
a klubok táblájába. A függvény a mysql_insert_id()-t használja, hogy
megkapja a felvett új tag azonosítóját.
440 23. óra
Mivel már rendelkezünk az új tag azonosítójával, meghívhatjuk a felvételéhez
szükséges újabb függvényt, ami a kozosfv.inc fájlban található.
A munkamenetFeltoltes() függvény egy azonosítót, egy belépési nevet és
egy jelszót vár paraméterül és hozzáadja azokat a $munkamenet tömbhöz.
Így ezek az értékek már elérhetõek lesznek minden munkamenetet kezelõ oldalunk
számára. Ezzel képesek leszünk a tag azonosítására a további oldalakon is.
23.7. program Részlet a kozosfv.inc fájlból
1: function munkamenetFeltoltes( $azonosito, $nev,
$jelszo )
2: {
3: global $munkamenet;
4: $munkamenet["azonosito"] = $azonosito;
5: $munkamenet["nev"] = $nev;
6: $munkamenet["jelszo"] = $jelszo;
7: $munkamenet["belepett"] = true;
8: }
Az azonosító, név és jelszó megadása mellett a belépési állapotot jelzõ értéket
(belepett) is beállítjuk a munkameneteket kezelõ oldalaink számára.
Végül, miután a csatlakozas.php oldal frissítette az adatbázist és a munkamenethez
rendelt értékeket, útjára engedhetjük új tagunkat. Meghívjuk a header()
függvényt, átirányítva a böngészõt a klubfrissites.php oldalra, ahol a tagnak
be kell majd állítania az újonnan bejegyzett klub részletes adatait.
A csatlakozas.php kimenetét a 23.2. ábrán láthatjuk.
Teljes példa (elsõ rész) 441
23
23.2. ábra
A csatlakozas.php
kimenete
klubfrissites.php
Ez az oldal kettõs célt szolgál. Egyrészt az új tagoknak itt kell megadniuk a klub
részletes adatait, a bejegyzett tagok pedig itt módosíthatják ezeket.
23.8. program klubfrissites.php
1: 2: include("adatbazis.inc");
3: include("kozosfv.inc");
4:
5: $klub_sor = azonositas();
6:
7: $uzenet = "";
8:
9: if ( isset( $mitkelltenni ) &&
$mitkelltenni=="frissites" )
10: {
11: if ( empty( $urlap["klubnev"] ) )
12: $uzenet .="A klubnév mezõ nincs
kitöltve!
\n";
13:
14: if ( ! sorLekeres( “teruletek”, “azonosito”,
$urlap["terulet"] ) )
15: $uzenet .= "KRITIKUS HIBA: A terület kódja
nem található!
";
16:
17: if ( ! sorLekeres( "tipusok", "azonosito",
$urlap["tipus"] ) )
18: $uzenet .= "KRITIKUS HIBA: A típus kódja
nem található!
";
19:
20: if ( $uzenet == "" )
21: {
22: klubFrissites( $munkamenet["azonosito"],
$urlap["klubnev"],
$urlap["terulet"],
23: $urlap["tipus"],
$urlap["email"],
$urlap["ismerteto"] );
24: header("Location: tagmenu.php?".SID);
25: exit;
26: }
27: }
442 23. óra
23.8. program (folytatás)
28: else
29: {
30: $urlap = $klub_sor;
31: }
32: ?>
33:
34:
35:
36: Klubinformációk frissítése
37:
38:
39:
40: 41: include("kozosnav.inc");
42: ?>
43:

Klubinformációk frissítése


44: 45: if ( $uzenet != "" )
46: {
47: print "$uzenet

";
48: }
49: ?>
50:
51:


52: value="frissites">
53: 54: value="">
55:
56:


57: Klub neve:

58: 59: value="stripslashes($urlap["klubnev"]) ?>">
60:


61:


62: Klub helye:

63:
66:


67:


68: Klub típusa:

69:
72:


73:


74: Kapcsolattartó e-mail címe:

75: 76: value="stripslashes($urlap["email"]) ?>">
77:


78:


79: Klub ismertetõje:

80:
83:


84:


85:
86:


87:

88:
89:
90:
Beillesztjük az adatbazis.inc és kozosfv.inc nevû külsõ állományainkat,
így rögtön kész adatbáziskapcsolattal és munkamenettel kezdjük az oldalt. Ezután
meghívjuk az új azonositas() nevû függvényt, ami a kozosfv.inc fájlban
található. Ez összehasonlítja a munkamenet adatait az adatbázissal.
23.9. program Részlet a kozosfv.inc fájlból
1: function azonositas( )
2: {
3: global $munkamenet, $belepett;
4: $munkamenet["belepett"] = false;
444 23. óra
23.9. program (folytatás)
5: $klub_sor = sorLekeres( "klubok", "azonosito",
$munkamenet["azonosito"] );
6: if ( ! $klub_sor ||
7: $klub_sor["nev"] != $munkamenet["nev"] ||
8: $klub_sor["jelszo"] != $munkamenet["jelszo"] )
9: {
10: header( "Location: belepes.php" );
11: exit;
12: }
13: $munkamenet["belepett"] = true;
14: return $klub_sor;
15: }
Az azonositas() jól átlátható függvény. A $munkamenet["azonosito"] elem
ét használjuk arra, hogy a sorLekeres() függvény segítségével lekérjük a klubhoz
tartozó sort az adatbázisból. Ezt a $klub_sor asszociatív tömbben tároljuk és
ellenõrizzük a nev és jelszo elemek egyezését a $munkamenet megfelelõ tömbelemeivel.
Ha nem egyeznek, a belepes.php oldalra küldjük a tagot.
Miért vállaljuk fel az adatbázis lekérdezésének költségét az azonosításhoz? Miért
nem egyszerûsítjük a problémát a belepett elem ellenõrzésére? Ez visszaéléseknek
engedne teret, mivel egy rosszindulatú látogató egyszerûen hozzáadhatna az
oldal címéhez egy ilyen részt:
munkamenet%5Bbelepett%5D=1&munkamenet%5Bazonosito%5D=1
így átvéve az 1-es azonosítóval rendelkezõ tag fölött az irányítást, a PHP ugyanis
ezt a $munkamenet tömbbé alakítja, amely egy felületesebb ellenõrzésen túljuthatna.
A rosszindulatú látogató most is alkalmazhat egy hasonló trükköt, hogy
belépést nyerjen, de mivel az adatbázisban lévõ névvel és jelszóval történõ egyez
ést vizsgáljuk, a „hamisított” $munkamenet változónak helyes tartalommal kell
rendelkeznie, így pedig felesleges a csalás.
Az azonositas() függvény mellékterméke a visszaadott tömb, amely a kérdéses
klubról az adatbázisban található összes adatot tartalmazza. Késõbb az oldalak ezt
az információt saját céljaikra használhatják fel. Miután az azonositas() függv
ény visszatér a klub adatait tartalmazó tömbbel, ezt a $klub_sor változónak
adjuk értékül.
Ismételten ugorjunk a HTML részre. Itt elõször a kozosnav.inc állományt
illesztjük be. Ebben a fájlban azonban továbblépünk az eddigieknél és szerepeltetj
ük a tagok menüjét is:
Teljes példa (elsõ rész) 445
23
23.10. program kozosnav.inc
1:


2:
Klubinformációk
|
3:
Eseményinformációk
|
4:
Csatlakozás
|
5: Belépés |
6: Honlap
7:


8: 9: if ( $munkamenet["belepett"] )
10: {
11: ?>
12:


13: ">
Bejegyzett események
|
15:
Új esemény
|
16:
Tagok honlapja

17:


18: 19: }
20: ?>
21:

Ha a $munkamenet["belepett"] igazra van állítva, a csak tagok számára
megjelenítendõ hivatkozásokat is kiírjuk. Vegyük észre, hogy minden hivatkozásban
megadjuk a SID állandót. Ez tartalmazza a munkamenet nevét és azonosító-
ját, így biztosítjuk, hogy az azonosító oldalról-oldalra átadódjon, még akkor is, ha
a sütik nincsenek bekapcsolva.
A klubfrissites.php oldal ûrlapja igazán figyelemreméltó. Az eddigieknek
megfelelõen a mitkelltenni és a munkamenetet azonosító rejtett mezõket is
felvesszük az ûrlapba. Szövegmezõket biztosítunk a klub neve, ismertetõje és
a kapcsolattartó elektronikus levélcíme számára. A klubtípusok és területek
lenyíló menüinek elõállítására egy új függvény, az optionLista() szolgál.
446 23. óra
23.11. program Részlet az adatbazis.inc fájlból
1: function optionLista( $tabla, $azon )
2: {
3: global $kapcsolat;
4: $eredmeny = mysql_query( "SELECT * FROM $tabla",
$kapcsolat );
5: if ( ! $eredmeny )
6: {
7: print "Nem lehet megnyitni: $tabla

";
8: return false;
9: }
10: while ( $egy_sor = mysql_fetch_row( $eredmeny ) ){
11: print "

Tagok honlapja


20:
21:
Klub részletei


22:
Bejegyzett események


23:
Új esemény


24:
25:
26:
Az oldalon egyetlen újdonság található. Miután meghívjuk az azonositas()
függvényt, hogy meggyõzõdjünk róla, hogy a látogatónk tag, az általa visszaadott
tömböt egy új függvénynek adjuk át. Ez a függvény, a klubAdatEllenorzes(),
a kozosfv.inc állományban található és azt ellenõrzi, hogy a tag megadta-e már
a klub adatait. Amíg egy tag ki nem tölti legalább a klub nevét, nem adhat rendezv
ényeket a rendszerhez.
Teljes példa (elsõ rész) 449
23
23.14. program Részlet a kozosfv.inc fájlból
1: function klubAdatEllenorzes( $klubtomb )
2: {
3: if ( ! isset( $klubtomb["klubnev"] ) )
4: {
5: header( "Location: klubfrissites.php?".SID );
6: exit;
7: }
8: }
belepes.php
Mielõtt továbblépünk a rendezvényeket kezelõ oldalakra, el kell készítenünk
a belepes.php programot. Ez az oldal ad lehetõséget a bejegyzett tagoknak,
hogy a késõbbiekben belépjenek a rendszerbe.
23.15. program belepes.php
1: 2: include("adatbazis.inc");
3: include("kozosfv.inc");
4:
5: $uzenet="";
6:
7: if ( isset( $mitkelltenni ) && $mitkelltenni ==
"belepes" )
8: {
9: if ( empty( $urlap["nev"] ) || empty(
$urlap["jelszo"] ) )
10: $uzenet .= "Ki kell töltenie minden
mezõt!
\n";
11:
12: if ( ! ( $sor_tomb =
13: jelszoEllenorzes( $urlap["nev"],
$urlap["jelszo"] ) ) )
14: $uzenet .= "Hibás név vagy jelszó, próbálkozzon
újra!
\n";
15:
450 23. óra
23.15. program (folytatás)
16: if ( $uzenet == "" ) // nem találtunk hibát
17: {
18: munkamenetFeltoltes( $sor_tomb["azonosito"],
$sor_tomb["nev"],
19: $sor_tomb["jelszo"] );
20: header( "Location: tagmenu.php?".SID );
21: }
22: }
23: ?>
24:
25:
26:
27: Belépés
28:
29:
30:
31:
32: 33: include("kozosnav.inc");
34: ?>
35:
36:

Belépés


37:
38: 39: if ( $uzenet != "" )
40: {
41: print "

$uzenet

";
42: }
43: ?>
44:
45:


46:


47: value="belepes">
48: 49: value="">
50:


51: Tagsági név:

52: 53: value="">
Teljes példa (elsõ rész) 451
23
23.15. program (folytatás)
54:


55: Jelszó:

56: value="">
57:


58:
59:


60:
61:
62:
Az oldal szerkezete már ismerõs kell, hogy legyen. Az adatbazis.inc és
kozosfv.inc állományokat használjuk, hogy adatbáziskapcsolatot létesítsünk és
aktív munkamenettel rendelkezzünk.
Ha a $mitkelltenni változó be van állítva és a várt "belepes" értéket
tartalmazza, ellenõrizzük az ûrlapról érkezett adatokat. Az új adatbazis.inc
függvényt használjuk arra, hogy az urlap["nev"] és urlap["jelszo"] érté-
keket vizsgáljuk.
23.16. program Részlet az adatbazis.inc fájlból
1: function jelszoEllenorzes( $nev, $jelszo )
2: {
3: global $kapcsolat;
4: $eredmeny = mysql_query( "SELECT azonosito, nev,
jelszo FROM klubok
5: WHERE nev='$nev' and
jelszo='$jelszo'",
6: $kapcsolat );
7: if ( ! $eredmeny )
8: die ( "jelszoEllenorzes hiba: "
.mysql_error() );
9: if ( mysql_num_rows( $eredmeny ) )
10: return mysql_fetch_array( $eredmeny );
11: return false;
12: }
452 23. óra
A jelszoEllenorzes() egy belépési nevet és egy jelszót vár. Ezek felhaszná-
lásával egy egyszerû SELECT lekérdezést küld az adatbázisnak a klubok táblájára
vonatkozóan.
Visszatérve a belepes.php oldalra, ha nem találunk hibát, meghívjuk
a munkamenetFeltoltes() függvényt, amely beállítja az azonosito, nev,
jelszo és belepett elemeket a $munkamenet tömbben. Ezután a tagot átirá-
nyítjuk a tagmenu.php oldalra.
esemenyfrissites.php
Most, hogy a tagok már képesek csatlakozni és belépni a rendszerbe, valamint
módosítani is tudják az adataikat, lehetõséget kell adnunk a rendezvények bevitelére
és módosítására. A teljes esemenyfrissites.php oldal a 23.17. programban
látható.
23.17. program esemenyfrissites.php
1: 2: include("adatbazis.inc");
3: include("kozosfv.inc");
4: include("datum.inc");
5:
6: $klub_sor = azonositas();
7: klubAdatEllenorzes( $klub_sor );
8:
9: $edatum = time();
10: $uzenet = "";
11:
12: if ( ! empty( $eazonosito ) )
13: $esemeny_sor = sorLekeres( "esemenyek",
"eazonosito", $eazonosito );
14: else
15: $eazonosito = false;
16:
17: if ( isset( $mitkelltenni ) &&
$mitkelltenni=="esemenyFrissites" )
18: {
19: if ( empty( $urlap["enev"] ) )
20: $uzenet .="Az eseménynek névvel kell
rendelkeznie!
\n";
21:
Teljes példa (elsõ rész) 453
23
23.17. program (folytatás)
22: if ( ! sorLekeres( "teruletek", "azonosito",
$urlap["eterulet"] ) )
23: $uzenet .= "KRITIKUS HIBA: A terület
kódja nem található!
";
24:
25: if ( ! sorLekeres( "tipusok", "azonosito",
$urlap["etipus"] ) )
26: $uzenet .= "KRITIKUS HIBA: A típus
kódja nem található!
";
27:
28: foreach ( array( "ehonap", "eev", "enap",
"eperc" )
29: as $datum_egyseg )
30: {
31: if ( ! isset( $urlap[$datum_egyseg] ) )
32: {
33: $uzenet .= "KRITIKUS HIBA: A dátum
nem értelmezhetõ!";
34: break;
35: }
36: }
37: $edatum = mktime( $urlap["eora"],
$urlap["eperc"], 0,
$urlap["ehonap"],
38: $urlap["enap"], $urlap["eev"] );
39:
40: if ( $edatum < time() )
41: $uzenet .= "Múltbeli dátum nem
fogadható el!";
42:
43: if ( $uzenet == "" )
44: {
45: esemenyModositas( $urlap["enev"],
$urlap["ehelyszin"],
$urlap["eterulet"],
46: $urlap["etipus"],
$urlap["ecim"], $urlap["eirsz"],
47: $urlap["eismerteto"],
$munkamenet["azonosito"],
$edatum,
48: $eazonosito );
49: header( "Location:
esemenylista.php?".SID );
50: }
454 23. óra
23.17. program (folytatás)
51: }
52: elseif ( $eazonosito )
53: {
54: //foreach( $esemeny_sor as $kulcs=>$ertek )
55: // $urlap[$kulcs] = $ertek;
56: $urlap = $esemeny_sor;
57: $edatum = $esemeny_sor["edatum"];
58: }
59: else
60: {
61: $urlap["eterulet"] = $klub_sor["terulet"];
62: $urlap["etipus"] = $klub_sor["tipus"];
63: }
64: ?>
65:
66:
67:
68: Esemény hozzáadása/frissítése
69:
70:
71:
72: 73: include("kozosnav.inc");
74: ?>
75:
76:

Esemény hozzáadása/frissítése


77:
78: 79: if ( $uzenet != "" )
80: {
81: print "$uzenet";
82: }
83: ?>
84:


85:


86: value="esemenyFrissites">
87: 88: value="">
Teljes példa (elsõ rész) 455
23
23.17. program (folytatás)
89: 90: value="">
91: Esemény neve:

92: 93: value="stripslashes($urlap["enev"]) ?>">
94:


95:


96: Dátum és idõ:

97:
100:
101:
104:
105:
108:
109:
112:
113:
116:


117:


118: Esemény helye:

119:
122:


123:


124: Esemény típusa:

125:
456 23. óra
23.17. program (folytatás)
128:


129:


130: Esemény ismertetõje:

131:
134:


135:


136: Helyszín:

137: 138: value="stripslashes($urlap["ehelyszin"])?>">
139:


140:


141: Helyszín címe:

142:
145:


146:


147: Helyszín irányítószáma:

148: 149: value="stripslashes($urlap["eirsz"]) ?>">
150:


151:


152:
153:


154:

155:
156:
157:
Ezen az oldalon az esemenyek táblának megfelelõ elemekkel készítünk egy ûrlapot.
Szokás szerint ellenõriznünk kell a beérkezõ értékeket és frissítenünk kell az adatbá-
zist. Ha azonban az oldal meghívása alapján úgy ítéljük, hogy nem esemény hozzá-
adása a cél, hanem módosítás, akkor le kell kérdeznünk az adatbázisból a módosí-
tandó adatokat. Az oldal meghívása során az $eazonosito változót kapja,
Teljes példa (elsõ rész) 457
23
ha egy meglévõ esemény módosítását kell elvégezni. Ha a változó nem üres,
a sorLekeres() függvényt alkalmazva kapjuk meg az $esemeny_sor tömbben
a rendezvény adatait. Ha az $eazonosito nincs megadva vagy üres, akkor hamis
értékre állítjuk.
Ha az oldal ûrlapkitöltés hatására hívódott meg, ellenõriznünk kell a beérkezett
adatokat. A dátummal kapcsolatban meg kell vizsgálnunk, hogy az nem egy múltbeli
érték-e. Ennek érdekében beállítunk egy $edatum nevû globális változót
a beadott adatok függvényében.
Ha az adatok megfelelnek az általunk támasztott követelményeknek,
az adatbazis.inc egy új függvényét hívjuk meg, melynek neve
esemenyModositas(). Ez a függvény minden olyan értéket vár, amit
az esemenyek táblában el kell helyeznünk. Az utolsó paraméter a rendezvény
azonosítószáma. Ezt az esemenyModositas() függvény arra használja, hogy
megállapítsa, új eseményt kell felvennie vagy módosítania kell egy már létezõt.
Figyeljük meg, hogy a klub azonosítószáma a $munkamenet["azonosito"]
változóban található, így ezt helyezzük az esemenyek tábla eklub mezõjébe.
A dátum adatbázisban történõ tárolására idõbélyeget használunk.
23.18. program Részlet az adatbazis.inc fájlból
1: function esemenyModositas( $enev, $ehelyszin,
$eterulet, $etipus, $ecim, $eirsz,
$eismerteto, $eklub, $edatum, $eazonosito )
2: {
3: global $kapcsolat;
4: if ( ! $eazonosito )
5: {
6: $lekeres = "INSERT INTO esemenyek (enev,
ehelyszin, eterulet, etipus,
7: ecim, eirsz, eismerteto, eklub,
edatum )
8: VALUES( '$enev', '$ehelyszin',
'$eterulet', '$etipus',
'$ecim',
9: '$eirsz', '$eismerteto', '$eklub',
'$edatum')";
10: }
11: else
12: {
458 23. óra
23.18. program (folytatás)
13: $lekeres = "UPDATE esemenyek SET enev='$enev',
ehelyszin='$ehelyszin',
14: eterulet='$eterulet',
etipus='$etipus',
ecim='$ecim',
eirsz='$eirsz',
15:
eismerteto='$eismerteto', eklub='$eklub', edatum='$edatum'
16: WHERE eazonosito='$eazonosito'";
17: }
18: $eredmeny = mysql_query( $lekeres, $kapcsolat );
19: if ( ! $eredmeny )
20: die ( "esemenyModositas hiba: "
.mysql_error() );
21: }
Látható, hogy a függvény az $eazonosito paraméter értékétõl függõen mûködik.
Ha hamis értékû, egy INSERT SQL parancs hajtódik végre a megadott adatokkal.
Egyéb esetben az $eazonosito egy UPDATE kérés feltételében szerepel.
Miután az adatbázist frissítettük, a tagot az esemenylista.php oldalra irányítjuk,
ahol a teljes rendezvénynaptárt láthatja.
Ha a tag még nem töltötte ki az ûrlapot, átugorjuk az ellenõrzõ és adatbázis-frissítõ
kódokat. Ha azonban rendelkezünk az $eazonosito változóval, már lekértük
az esemény információit az adatbázisból és az ûrlapra írhatjuk azokat. Ezt úgy tehetj
ük meg, hogy az $esemeny_sor változót értékül adjuk az $urlap változónak,
az $edatum változót pedig az $esemeny_sor["edatum"] értékével töltjük fel.
Ha nem kaptunk ûrlapértékeket és $eazonosito változónk sincs,
az $urlap["terulet"] és $urlap["tipus"] elemeknek a klubnak megfelel
õ adatokat adjuk értékül a $klub_sor tömbbõl. Ezzel a megfelelõ lenyíló men
ükben a klubokhoz tartozó értékek lesznek alapbeállításban kiválasztva.
A HTML ûrlapon az egyetlen említésre méltó kód a dátum és idõ számára készített
lenyíló menüket állítja elõ. Ezeket a menüket elég egyszerûen beépíthettük volna
a PHP kódba, de szükségünk van arra, hogy alapbeállításban az aktuális idõt,
a tag által korábban választott idõt, vagy az esemenyek táblában tárolt idõt jelezz
ék. Az alapbeállításban kiválasztandó értéket már elhelyeztük az $edatum változ
óban. Ezt a program elején az aktuális idõre állítottuk be. Ha beérkezõ adatokat
észlelünk, annak megfelelõen állítjuk be ezt az értéket. Egyéb esetben, ha már
meglévõ eseményt módosítunk, az esemenyek tábla edatum mezõjének értékét
adjuk az $edatum változónak.
Teljes példa (elsõ rész) 459
23
Minden lenyíló menühöz az $edatum változóban lévõ idõbélyeget adjuk át
a megfelelõ függvénynek. Ezek az új datum.inc nevû külsõ állományban
találhatók.
23.19. program Részlet a datum.inc fájlból
1: function honapLehetosegek( $datum )
2: {
3: $datum_tomb = getDate( $datum );
4: $honapok = array( "Jan","Feb","Már",
"Ápr","Máj","Jún",
5: "Júl","Aug","Szep",
"Okt","Nov","Dec" );
6: foreach ( $honapok as $kulcs=>$ertek )
7: {
8: print "VALUE=\"".($kulcs+1)."\"";
9: print ( ( $datum_tomb["mon"] ==
($kulcs+1) )?"SELECTED":"" );
10: print ">$ertek\n";
11: }
12: }
13: function napLehetosegek( $datum )
14: {
15: $datum_tomb = getDate( $datum );
16: for ( $x = 1; $x<=31; $x++ )
17: {
18: print "