Szegedi Tudományegyetem Informatikai Tanszékcsoport DIPLOMAMUNKA Bártol Lajos 2008
Szegedi Tudományegyetem Informatikai Tanszékcsoport Adatbázis-kezelés PHP + MySQL környezetben Diplomamunka Készítette: Bártol Lajos programtervező matematikus hallgató Témavezető: Dr. Balázs Péter egyetemi tanársegéd Szeged 2008
Feladatkiírás A feladat a PHP programozási nyelv és a MySQL relációs adatbázis-kezelő rendszer kapcsolatának szemléltetése egy testreszabott webes felületen keresztül, mintaadatbázis és a hozzá kapcsolódó gyakorlati példák megkonstruálásával. A létrehozott alkalmazás segítségével váljék lehetővé: 1. a PHP nyelv adatbáziskezelés-orientált bemutatása 2. a MySQL adatbázis-kezelő rendszer célratörő ismertetése 3. egy, a feladathoz elegendően komplex mintaadatbázis prezentálása 4. a mintaadatbázishoz kapcsolódó példaprogramok elemzése 2
Tartalmi összefoglaló A téma megnevezése: Adatbázis-kezelés PHP + MySQL környezetben A megadott feladat megfogalmazása: A feladat PHP nyelv segítségével MySQL adatbázis-programozás, egy komplex, de átlátható SQL alapú mintaadatbázis megalkotása, ennek adatokkal való feltöltése. Feladat továbbá a hozzá kapcsolódó mintafeladatok létrehozása és a megoldások kidolgozása, valamint egy telepítő modul biztosítása, mely az adtabázis létrehozásáért és feltöltéséért felelős. A megoldási mód: Legelőször egy webes felületet tervezünk, mely PHP + MySQL motorra épül. Ezután lépésről lépésre kidolgozzuk a komponenseit. A PHP menüpont alatt a nyelv sajátosságait ismertetjük adatbázis-kezelésre kiélezve, helyben kipróbálható, letölthető példaprogramokkal. A MySQL menüpont alatt az SQL nyelv alapjait irányadónak véve a MySQL adatbáziskezelő rendszer nyújtotta lehetőségeket taglaljuk. Ezt követően a MINTA menüpont alatt a mintaadatbázis létrehozásáért, illetőleg alaphelyzetbe állításáért felelős elemeket programozzuk le, majd komponensekre lebontva demonstráljuk az adatbázis felépítését, illetőleg szabad navigálási lehetőséget biztosítunk. Végezetül a GYAKORLAT menüpont alatt gyakorló feladatokat hozunk létre. A PHP részben bemutatott anyagot kvízszerű kérdések ellenőrzik, a MySQL részhez kapcsolódóan viszont kifejlesztünk egy beviteli felületet, melynek segítségével az esetleges megoldások kipróbálhatóak, illetőleg jelszó ismeretében megtekinthetőek. Alkalmazott eszközök, módszerek: Alkalmazott szoftver-eszközök, melyek a webes felület létrehozását segítették: o Photoshop CS3 o Flash CS3 o Notepad++ 3
Alkalmazott szoftver-eszközök, melyek a PHP+MySQL motor elkészítését segítették: o Notepad++ o phpmyadmin 2.11.5 o WOS Portable II (PHP5 5.2.5, Apache 2.2.8 + MySQL5 5.0.45 szerver egységes működtetése - freeware) Alkalmazott szoftver-eszközök, melyek a prezentációt segítették: o MS Visio 2007 o MS Word 2003 o ACDSee 9 Photo Manager Alkalmazott szoftver-eszközök, melyek a telepítőcsomag elkészítését segítették: o Install Creator - freeware Használt programozási és szabványos lekérdező nyelvek: o PHP o SQL o HTML o CSS o JavaScript Elért eredmények: A Diplomamunka eredményeként létrejött egy olyan felhasználói interfész, valamint egy olyan, a gyakorlati életből vett mintaadtabázist tartalmazó csomag, melynek segítségével könnyen és hatékonyan megismerhető a PHP + MySQL rendszerek működése, illetőleg az említett rendszerek nyújtotta lehetőségek alkalmazása is tanulmányozható. Kulcsszavak: Adatbázis, adatbázis-kezelő rendszer, dinamikus weboldal, szerver oldali programozás, PHP, MySQL, PHP gyakorlatok, SQL gyakorlatok 4
Tartalomjegyzék Feladatkiírás... 2 Tartalmi összefoglaló... 3 Tartalomjegyzék... 5 Bevezetés... 6 1. A PHP nyelv néhány sajátossága, adatbázis-orientált megközelítése... 7 1. 1. Alapok... 7 1. 1. 1. A PHP általános jellemzői... 7 1. 1. 2. A PHP programozás alapkövei... 8 1. 1. 3. A PHP és a HTML integrációs lehetőségei... 10 1. 2. Űrlapok... 11 1. 2. 1. A HTML űrlap nyújtotta előnyök... 11 1. 3. Kapcsolatteremtés a MySQL adatbázis-kiszolgálóval... 16 1. 3. 1. Csatlakozás... 16 1. 4. PHP adatbázis-kezelés nyújtotta alternatív lehetőségek... 17 2. A MySQL adatbázis-kezelő rendszer... 22 2. 1. Néhány szó a MySQL-ről... 22 2. 1. 1. A relációs adatbázis-kezelő rendszer (RDBMS)... 22 2. 1. 2. Mi a MySQL?... 22 2. 2. A MySQL alkotóelemei... 22 3. Az elkészített alkalmazás környezetének telepítése... 25 4. A mintaadatbázis bemutatása... 26 4. 1. A mintaadatbázis felépítése... 26 4. 2. A mintaadatbázis telepítése... 30 4. 3. Szabad navigáció... 31 5. Kidolgozott gyakorlatok... 32 5.1. A gyakorlatokhoz kapcsolódó interface ismertetése... 32 5.2. Az alkalmazás PHP feladatainak elemzése... 36 5.3. Az alkalmazás SQL feladatainak elemzése... 39 Irodalomjegyzék... 44 Nyilatkozat... 45 Köszönetnyilvánítás... 46 5
Bevezetés Már az 1900 as évek elején felmerült egy olyan adattárolási igény, mely az információk hatékony, gépesített tárolására és gyors visszanyerésükre irányult. Az adatbázisok fejlettebb formái csak az 1960-as évek közepétől kezdtek el teret hódítani. A legelső adatmodell, melyben szeparálódott a logikai és a fizikai adatbázis, a relációs adatmodell volt, melyet 1970-ben publikált Edgar F. Codd, az IBM munkatársa. A lekérdezés nyelve azonban nehézkes, komplex logikai követelményeknek volt alárendelve, ami igencsak elégedetlen körülményeket szült a felhasználók körében. A lekérdező nyelv problémájára megoldást keresve és a relációs adatmodell elvi alapjait felhasználva az adatbázis és az adatok kezelésére kifejlesztett programnyelv az SQL lett (Structured Query Language, IBM), mely eredetileg a Structured English Query Language, SEQUEL nevet kapta. 1986-ban az SQL, mint a relációs adatbázisok lekérdezőnyelve az Egyesült Államokban is, és Európában is szabványossá vált. [1] Az adatbázis-kezelés, a program által vezérelt adatbázis menedzselés szerves részét képezi napjaink informatikai életének. Az SQL nyelvet alapul véve több relációs adatbáziskezelő rendszer is kifejlődött, közülük az egyik legelterjedtebb a MySQL. Több programnyelv (mint pl. a PHP, C, C++, C#, Python, Java, stb.) számára hatékony hozzáférést biztosít. A PHP szintén egy elterjedt nyílt forráskódú, szerver-oldali programozási nyelv, mely különösen alkalmas arra, hogy webes felületen keresztül adatbázis-manipulációkat hajtsunk végre. A PHP és a MySQL szorosan összenőtt, jelentőségük abban áll, hogy platformfüggetlenek, költséghatékonyak és akár robusztus, komplex alkalmazások fejlesztésére is alkalmasak. A későbbiekben taglaljuk a PHP nyelv nyújtotta néhány strukturális, és a MySQL adatbázis-kezelést érintő lehetőségét, kitérünk magára a MySQL adatbáziskezelő rendszerre, mint az SQL nyelv egy elterjedt implementációjára, valamint a mintaadatbázis bemutatása után kidolgozott gyakorlatokkal segítjük felfedezni az említett rendszerek rejtelmeit. 6
1. A PHP nyelv néhány sajátossága, adatbázis-orientált megközelítése 1. 1. Alapok A nyelv rövid, szerkezeti-, illetőleg adatbázis-kapcsolati bemutatását megelőzően mindenképp hasznos támpont az alapfogalmak megismerése, valamint néhány kulcsfontosságú kérdés megválaszolása. 1. 1. 1. A PHP általános jellemzői A PHP túlnőtt eredeti jelentőségén. Kezdetben személyes honlapok karbantartási céljaira készült, amit eredeti elnevezése is tükröz (Personal Home Page Tools). Mostanra már az angol Hypertext Preprocessor rekurzív mozaikszóval azonosíthatjuk. Az idők folyamán kibővítették lehetőségei tárházát, így megszületett egy önálló interpretált programozási nyelv, mely kiválóan alkalmas dinamikus weblapok készítéséhez. Szerkezetét tekintve leginkább a C nyelvhez hasonlít. A PHP kódok végezhetnek adatbázis-lekérdezéseket, dinamikusan létrehozhatnak képeket, fájlokat olvashatnak és írhatnak, kapcsolatot létesíthetnek távoli szerverekkel. A lehetőségek száma korlátlan. A HTML (angolul: HyperText Markup Language) leíró nyelv által készített weboldalak tartalma állandó, csak manuális átszerkesztéssel változik (például bemutatkozó oldalak). Ezek a statikus weblapok. Dinamikus weblapok azok az oldalak melyek tartalmát program generálja. A kliens, azaz jelen estben a böngésző (Internet Explorer, Firefox, Opera, stb.), a neki megadott webcím (URL) alapján megkeresi a kiszolgálót (webszerver), lekéri, értelmezi és megjeleníti a megadott címen található weblapot. Népszerű webszerver az Apache. Telepítése után a gépünk lokális kiszolgálóként használható, melyre a localhost domain névvel vagy az 127. 0. 0. 1 IP-címmel hivatkozhatunk. Működését ellenőrizhetjük, ha a böngészőnkbe a http://localhost URL-t írjuk. 7
Fejlesztés során a HTML nyelvű weblapok forrásszövegébe PHP programrészeket illesztünk. Az interpreter (értelmező) nem generál gépi kódot, a beírt kód végrehajtása lényegében a kód utasításonkénti értelmezésével történik. Az Apache-ba integrált PHPértelmező végrehajtja a PHP programrészeket, melynek eredményeként egy módosított HTML-kód generálódik, és az Apache ezt a weblapot küldi ki a kliens felé. A PHP program függvényhívásokon keresztül éri el a MySQL szervert, és az adatbázisból lekért adatokkal építi fel a dinamikus weblapot. Néhány megcáfolhatatlan érv szól amellett, hogy a PHP-t érdemes választani. Nyílt forráskódjából adódóan jó támogatással bír, amit a képzett fejlesztői gárda és az elkötelezett közösség szolgáltat. A legtöbb kiszolgálóprogrammal együttműködve, operációs rendszerek szinte bármelyikén képes futni. A CH Software által fejlesztett WOS Portable ingyenes programcsomag. Egyben tartalmaz Apache-ot, PHP-t és MySQL-t, valamint egy egyedi felületen keresztül könnyedén biztosítja ezek hatékony üzemeltetését és monitorozását. Gombnyomással gépünk webszerverré válhat és az adatbázis kiszolgáló is rendelkezésünkre áll. Leginkább a népszerű, hasonló funkciókat ellátó XAMPP csomaghoz hasonlítható. [2] 1. 1. 2. A PHP programozás alapkövei A PHP - mint a legtöbb programozási nyelv - rendelkezik azon szükséges alapkövekkel, melyek lehetővé teszik számunkra programjaink, alkalmazásaink hatékony felépítését. Ezek a változók, függvények és vezérlési szerkezetek. Változót deklarálni nem kell, típusát az első értékadás határozza meg. A kis- és nagybetű különbözőnek számít. Újabb értékadás megváltoztathatja a típust, például: $x = 4; $x = alma ; A változók tehát rugalmasan használhatók: egyszer szám, másszor esetleg karakterlánc lehet bennük. A változók különleges tárolók, melyeket azért hozunk létre, hogy értéket helyezzünk el bennük. Egy dollárjelből ($) és egy tetszőlegesen választott névből tevődnek össze. A név betűket, számokat és alulvonás karaktereket tartalmazhat (számmal azonban nem kezdődhet). A számokon és betűkön kívül más egyéb karakterek nem megengedettek. 8
A PHP 5 az adattípusokat úgy kezeli, mintha a típus az adathoz rendelt kiegészítő információ lenne. Nagyobb méretű programokban hátrányt jelenthet, ha egy adott típusú értéket várunk egy változótól, míg az egy teljesen más típusú értéket tartalmaz. A PHP 5 fontosabb adattípusai az Integer (egész szám), a String (karakterlánc), a Boolean (logikai változó, értéke igaz vagy hamis), és az Array (tömb). Funkcionalitását tekintve a nyelv terjedelmes fügvénykészlettel rendelkezik, továbbá támogatja a lehetőségét annak, hogy saját, testreszabott függvényeket is deklaráljunk. A függvény valójában egy zárt, önálló kódrészlet, melyet programunkból meghívhatunk. Amikor meghívjuk, az adott függvényblokk tartalma végrehajtódik. Feldolgozás céljából adatokat adhatunk át neki. A függvényhívónak többnyire értéket ad vissza, azonban vannak függvények, melyeknek nincs visszatérési értékük, hiváskor csupán a hozzájuk rendelt feladatot teljesítik. A függvény nevét követő, zárójelben elhelyezett változók értékei, a híváskor átadott paraméterek lesznek. A függvényeknek visszatérési értéke is lehet, ehhez a return utasításra van szükség. A return befejezi a függvény futtatását és az utána írt kifejezést küldi vissza a hívónak. Amennyiben olyan függvényt hozunk létre, amelynek nem kívánunk paramétereket adni, a nevét követő zárójelet üresen hagyjuk. Függvények létrehozásakor az alábbi sablon követendő: function valamilyen_fuggveny ($parameter_1,, $parameter_n ) { // ez a függvény törzse return valami; //megadása nem kötelező } A PHP vezérlési szerkezeteit fókuszpontba helyezve, több konstrukció is rendelkezésünkre áll. Legfontosabbak: az if, a switch, a while, a do..while, és a for szerkezeti elemek. A C nyelv szintaxisához hasonló módon ezen szerkezetek feltételét zárójelbe tesszük, míg az egyes ágak, blokkok tartalmát kapcsos zárójelek ölelik fel. 9
1. 1. 3. A PHP és a HTML integrációs lehetőségei A HTML dokumentumokhoz hasonlóan a PHP állományok is tisztán szövegfájlok. Bármilyen szövegfájl szerkesztésére alkalmas programmal készíthetünk PHP állományokat. A PHP oldalak írásakor tudatnunk kell a feldolgozóval, mely részeket hajtsa végre. Ha nem adjuk meg, hogy a fájl mely részei tartalmaznak PHP kódot, az értelmező mindent HTMLnek tekint és változtatás nélkül továbbküldi a böngésző számára. A PHP programkódot a HTML forrásszövegébe ágyazzuk. A fájlnév kiterjesztése.php kell legyen, így a webszerver PHP modulja értelmezi és végrehajtja a <?php?> vagy <??> tagek között elhelyezett PHP kódot. A nyitó- és záró elemek közé a kód kimenetét helyettesíti, majd az ily módon meggenerált weblapot elküldi a kliensnek, mely megjeleníti az eredményt. A PHP feldolgozó figyelmen kívül hagy mindent, ami a PHP nyitó- és záró elemein kívül esik. A következő példa azt szemlélteti, miként ágyazódik be a PHP program a HTML tartalomba. A program számokat ír ki karaktereik növelésével, majd csökkentésével. Mindezt az i ciklusváltozó folyamatosan módosított értéke teszi lehetővé. A példaprogram a mellékelt CD wosportable\www\diplomamunka\php\peldak\src könyvtárában található meg program_02_src.php néven, illetőleg tesztelhető a mellékelt alkalmazás PHP szekciójának Alapok\HTML és PHP együtt menüpontja alatt. <html> <body> <?php print '<h1>számkiiratás...</h1>'; for ($i=0; $i <8; $i++) { print "<font face=arial size=$i><b>$i</b></font> \n"; } for ($i=8; $i> -1; $i--) { print "<font face=arial size=$i><b>$i</b></font> \n"; }?> </body> </html> 1.1.3. ábra: A fenti példaprogram kimenete 10
Egy dokumentumban a HTML elemek közé tetszőleges számú PHP kódblokk írható. Bár több kódblokkot helyezhetünk el egy dokumentumon belül, ezek együttesen alkotnak egy programot. Bármi, amit egy megelőző blokkban határoztunk meg (változók, függvények vagy osztályok), a dokumentumon belül elérhető lesz a későbbi blokkokban is. A több együttműködő, összességében egy nagyobb programot megvalósító PHP fájlt nevezzük PHP alkalmazásnak. 1. 2. Űrlapok Jelen esetben űrlap alatt a mindennapi életben használatos, adatok begyűjtésére szolgáló nyomtatvány elektronikus mását értjük. Jelentősége abban áll, hogy megkönnyíti az adatbevitelt a felhasználók számára. Egyszerűen és gyorsan továbbíthatják adataikat az adatbázis-kezelő rendszer felé. Az űrlapon elhelyezkedő beviteli mezők, radio- és nyomógombok, jelölőnégyzetek (checkbox) és legördülő menük a szerver felé történő hatékony információáramlást segítik. 1. 2. 1. A HTML űrlap nyújtotta előnyök Egy űrlap általában két részből áll, egy HTML fájlból és egy PHP feldolgozóból, azonban a tartalmak integrálására is van lehetőség. Amennyiben külön fájl felel a beviteli adatokért és külön fájl a feldolgozásért, a következő módon kell eljárni. A HTML fájlban egy form taget kell deklarálnunk, melynek paraméterként átadjuk a PHP feldolgozónk nevét, valamint az adatátvitel módját. A GET metódus az URL-hez kapcsolt kódolt paraméterek segítségével, a POST metódus viszont a háttérben küldi át az információkat szerveroldalra. A form törzsét az adatbevitel szempontjából legmegfelelőbbnek vélt komponensekkel töltjük fel (pl. beviteli mező, nyomógomb stb.). Az alábbiakban bemutatott HTML űrlap egy felhasznalo nevű szövegmezőt, egy cim nevű szövegterületet, és egy nyomógombot tartalmaz. A form elem action paraméterében megadott program_10_src.php fájl dolgozza majd fel az űrlapon megadott adatokat. A HTML és PHP kódot tartalmazó fájloknak egy könyvtárban kell lenniük. 11
<html> <head> <title>példa egy egyszerű HTML űrlapra</title> </head> <body> <form action="program_10_src.php" method="get"> Felhasználó:<br> <input type="text" name="felhasznalo"><br> Cím:<br> <textarea name="cim" rows="5" cols="40"> </textarea><br> <input type="submit" value="rendben"> </form> </body> </html> 1.2.1. ábra: A fenti példa kitöltött űrlapja Az űrlapon felvitt adatokra a name paramétereknek megadott azonosítók hivatkoznak. A $felhasznalo és a $cim változók értéke nem más, mint a HTML űrlap felhasznalo szövegmezőjének és cim területének a tényleges értéke. A következő program az előbb bemutatott űrlap adatait felhasználva, a megadott felhasználónevet és címet írja ki a képernyőre. <html> <head> <title>űrlap feldolgozás</title> </head> <body> <?php?> print "A neve: <b>$felhasznalo</b><br>"; print "A címe: <b>$cim</b>"; </body> </html> 12
1.2.2. ábra: A fenti űrlapfeldolgozó példa kimenete A fent említett két példaprogramot egy egészként kezeljük. A mellékelt CD wosportable\www\diplomamunka\php\peldak\src könyvtárában megtalálható az űrlap program_10_src.htm néven és feldolgozója program_10_src.php néven, illetőleg tesztelhető a mellékelt alkalmazás PHP szekciójának Űrlapok\Egy egyszerű HTML űrlap menüpontja alatt. Amennyiben az űrlapot és a hozzá tartozó feldolgozó részt együtt szeretnénk implementálni, az űrlap action paraméterének a fájl saját nevét kell megadni. Ezt akár a $PHP_SELF értékkel is megtehetjük, mely magát a fájlt reprezentálja. Gyakorta felmerül annak igénye, hogy egyszerre több elemet jelöljünk meg az űrlapon. Egyszerre több elem kiválasztását a select (választó lista), illetve a checkbox (jelölőnégyzet) kulcsszó biztosítja úgy, hogy az adott elemet definiáló name paraméternek egy tetszőleges nevet, majd egy üres szögletes zárójelet adunk meg. Így jelezzük a PHP felé, hogy tömbökkel szeretnénk dolgozni. Erre azért van szükség, hogy a kiválasztott elemekre kényelmesen, akár egy ciklus segítségével is hivatkozhassunk. <html> <head> <title>select elemet tartalmazó HTML űrlap</title> </head> <body> <form action="program_11_src.php" method="post"> <input type="text" name="felhasznalo"> <br> <textarea name="cim" rows="5" cols="40"> </textarea><br> <select name= "termekek[]" multiple> <option> Alaplap <option> Hangfal <option> Memória <option> Monitor </select><br> <input type="submit" value="rendben"> </form> </body> </html> 13
1.2.3. ábra: A fenti példa kitöltött űrlapja A select elemet jelölőnégyzetekkel (checkbox) helyettesítve hasonló eredményt érünk el, a különbség főként a megjelenést, a design-t érinti. <input type="checkbox" name="termekek[]" value="alaplap">alaplap <input type="checkbox" name="termekek[]" value="hangfal">hangfal <input type="checkbox" name="termekek[]" value="memoria">memória <input type="checkbox" name="termekek[]" value="monitor">monitor 1.2.4. ábra: A fenti példa kitöltött űrlapja A több elemet megjelölő űrlap feldolgozása ciklussal történik. Amennyiben ki szeretnénk iratni a felhasználó által megjelölt elemeket, egy foreach ciklust hívunk segítségül, 14
mely a korábban definiált tömbünk minden elemén végiglépked, majd a magjában megadott utasítás szerint megjeleníti az eredményt. <html> <head> <title> Program a fenti példában látott űrlap feldolgozására </title> </head> <body> <?php print "Üdvözlet:<b>$felhasznalo</b><br><br>"; print "A címe:<b>$cim</b><br><br>"; print "A következo termékeket választotta:<br>"; print "<ul>"; foreach ( $termekek as $termek ) { print "<li>$termek<br>"; } print "</ul>";?> </body> </html> 1.2.5. ábra: A fenti űrlapfeldolgozó példa kimenete A fent említett select elemeket tartalmazó példaprogramot és feldolgozóját egy egészként kezeljük. A mellékelt CD wosportable\www\diplomamunka\php\peldak\src könyvtárában megtalálható az űrlap program_11_src.htm néven és feldolgozója program_11_src.php néven, illetőleg tesztelhető a mellékelt alkalmazás PHP szekciójának Űrlapok\Több elem kiválasztása menüpontja alatt. 15
1. 3. Kapcsolatteremtés a MySQL adatbázis-kiszolgálóval A PHP nyelv egyik meghatározó tulajdonsága, hogy nagyon könnyen képes adatbázisokhoz csatlakozni és azokat kezelni. Azért esett a választás éppen a MySQL-re, mert ingyenes, ugyanakkor nagyon hatékony eszköz, amely képes megfelelni a valós feladatok által támasztott igényeknek is. 1. 3. 1. Csatlakozás Mielőtt elkezdhetnénk dolgozni az adatbázissal, csatlakoznunk kell a kiszolgálóhoz. A PHP-ben erre a mysql_connect() függvény szolgál. A függvény három karakterláncot vár paraméterként: a szerver, illetve a felhasználó nevét és a jelszót. Ha ezek egyikét sem adjuk meg, a függvény feltételezi, hogy a kérés a localhost-ra (azaz a helyi gépre) vonatkozik és felhasználóként a PHP-t futtató felhasználót, jelszóként pedig egy üres karakterláncot ad át. A mysql_connect() függvény siker esetén egy kapcsolatazonosítót ad vissza, amelyet egy változóba mentünk, hogy a későbbiekben folytathassuk a munkát az adatbáziskiszolgálóval. Az alábbi kódrészlet a mysql_connect() függvény segítségével kapcsolódik a MySQL adatbáziskiszolgálóhoz, illetőleg hiba esetén figyelmeztet és leáll. $kapcsolat = mysql_connect("localhost", "root", "jelszo"); if (!$kapcsolat) die("nem lehet csatlakozni a MySQL kiszolgálóhoz!"); Miután kialakítottuk a kapcsolatot a MySQL szerverrel, ki kell választanunk, melyik adatbázissal szeretnénk dolgozni. Erre a célra a mysql_select_db() függvény szolgál, amelynek meg kell adnunk a kiválasztott adatbázis nevét és szükség szerint egy kapcsolatazonosító értéket. Ha ez utóbbit elhagyjuk, automatikusan a legutoljára létrehozott kapcsolat helyettesítődik be. A mysql_select_db() függvény igaz értéket ad vissza, ha az adatbázis létezik és jogunk van a használatára. A következő kódrészlet a bemutato nevű adatbázist választja ki. $adatbazis = "bemutato"; mysql_select_db($adatbazis) or die ("Nem lehet megnyitni a következő adatbázist: $adatbazis!"); 16
1. 4. PHP adatbázis-kezelés nyújtotta alternatív lehetőségek Legelőször egy bemutato nevű adatbázist kell létrehoznunk, melyen futtathatjuk az adatbázis-környezetet igénylő PHP alapú feladatainkat, illetve prezentálhatjuk az eredményt. Erre a mellékelt program MINTA menüpont alatti Mintaadatbázis\Management szekciójában a Bemutató adatbázis létrehozása címszó alatt van lehetőség (lásd 1.4.1. ábra), illetőleg phpmyadmin alkalmazás segítségével vagy kézzel, parancssoros felületről. A phpmyadmin egy ingyenes, nyílt forráskódú PHP alkalmazás, mely vizuális felületet létesít az adatbázisok menedzselésére. Megjeleníthetjük és írhatjuk vele az adatbázisok tartalmát a szerveren (vagy a kliensnél), ahol a MySQL telepítve van. Ezen az interfészen keresztül létrehozhatunk, módosíthatunk adatbázisokat, táblákat, megváltoztathatjuk az egyes mezők tartalmát, adattípusát. A későbbiek folyamán említésre kerülő környezeti telepítést követően rendelkezésre áll a phpmyadmin 2.11.5-ös verziója is, és böngészőből, a http://localhost/phpmyadmin címmel lehet rá hivatkozni. Belépésnél user-t kell megadni felhasználóként, jelszó pedig nincs. A user felhasználó a root felhasználó jogosultsági mintájára készült, azaz teljes írási és olvasási joggal rendelkezik az összes adatbázis táblája felett. 1.4.1. ábra: A bemutato adatbázis létrehozása egyedi felületről 17
A bemutato adatbázis mindössze egy négy mezővel rendelkező adatok táblát tartalmaz, mely a fent említett telepítés során az adatbázissal együtt jön létre. Alapul a mellékelt CD wosportable\www\diplomamunka\minta\db\bemutato.sql scriptje szolgál. Az id mező lesz az elsődleges kulcs (PRIMARY KEY), mely nem vehet fel nullát és automatikusan növel (AUTO INCREMENT) egy egész értéket, ahogy újabb bejegyzések kerülnek a táblába. A nev mező változó számú karaktert tartalmazhat (VARCHAR), a nem mező egyetlen karaktert (F vagy N), az email mező pedig a felhasználó elektronikus levélcímét tárolja. 1.4.2 ábra: A bemutato adatbázis adatok táblájának szerkezete Az adatok felviteléhez össze kell állítanunk és le kell futtatnunk egy SQL parancsot. Erre a célra a PHP-ben a mysql_query() függvény szolgál. A függvény paraméterként egy SQL parancsot tartalmazó karakterláncot és szükség szerint egy kapcsolatazonosítót vár. Ha a program sikeresen lefutott, a mysql_query() pozitív értéket ad vissza, ha azonban formai hibát tartalmaz vagy nincs jogunk elérni a kívánt adatbázist, a visszatérési érték hamis lesz. Meg kell jegyeznünk, hogy egy sikeresen lefutott SQL program nem feltétlenül okoz változást az adatbázisban vagy tér vissza valamilyen eredménnyel. A felhasználó által megadott adatokat, mint az már említésre került, célszerű űrlapokon keresztül feldolgozni. Az alábbi kódrészlet azt mutatja be, miként szúrhatunk be űrlap segítségével felhasználó által megadott adatokat az adatbázisba. <?php global $PHP_SELF; $kapcsolat = mysql_connect('localhost','user',''); if (!$kapcsolat){ $hiba = "Nem lehet kapcsolódni a MySQL kiszolgálóhoz!"; return false; } if (! mysql_select_db('bemutato', $kapcsolat)){ $hiba = mysql_error(); return false; } 18
print "<form action=\"$php_self\" method=\"post\">"; print "Név<br>"; print "<input type=\"text\" name=\"nev\" size=\"30\">"; print "<br>"; print "E-mail cím<br>"; print "<input type=\"text\" name=\"email\" size=\"30\">"; print "<br><br>"; print "<select name=\"nem\">"; print "<option value=\"n\"> Nő"; print "<option value=\"f\"> Férfi"; print "</select><br><br>"; print "<input type=\"submit\" name=\"submit\" value=\"elküld\">"; print "</form>"; if ($_POST['submit'] == 'Elküld'){ if (($_POST['nev'] == '') && ($_POST['email'] == '')){ print "Hiányos kitöltés!"; } else { $parancs = "INSERT INTO adatok(nev,nem,email) VALUES ('$nev','$nem','$email') "; if (mysql_query($parancs)){ print "Az adatfelvitel sikeres!"; } else print "Hiba történt!"; } } mysql_close($kapcsolat);?> A fenti kódrészlettel kapcsolatos teljes példaprogram a mellékelt CD wosportable\www\diplomamunka\php\peldak\src könyvtárában, program_15_src.php néven található. Adataink lekérdezésére a mysql_query() függvényen keresztül kiadott SELECT utasítást ad lehetőséget. Miután egy sikeres SELECT lefutott, a mysql_query() visszaad egy eredményazonosítót, melyet felhasználva elérhetjük az eredménytáblát és a szükséges információkat. Miután végrehajtottuk a SELECT lekérdezést és az eredményazonosítót tároltuk, egy ciklus segítségével férhetünk hozzá az eredménytábla soraihoz. A PHP egy belső mutató segítségével tartja nyilván, hogy melyik sort olvastuk utoljára. Ha kiolvasunk egy eredménysort, a program automatikusan a következőre ugrik. A mysql_fetch_row() függvénnyel kiolvashatjuk a belső mutató által hivatkozott sort az eredménytáblából. A függvény paramétere egy eredményazonosító, visszatérési értéke pedig egy tömb, amely a sor összes mezőjét tartalmazza. Ha elértük az eredménykészlet végét, a mysql_fetch_row() függvény false értékkel tér vissza. A kiszolgálóhoz való kapacsolódás és az adatbázis kiválasztása után a mysql_query() függvénnyel egy SELECT lekérdezést küldünk az adatbázis kiszolgálójához. Az eredményt az $eredmeny változóban tároljuk, amit az eredménysorok számának lekérdezéséhez használunk. 19
A while kifejezésben a mysql_fetch_row() függvény visszatérési értékét az $egy_sor változóba töltjük. Az értékadó kifejezés értéke megegyezik a jobb oldal értékével, ezért a kiértékelés során a kifejezés értéke mindig igaz lesz, amíg a mysql_fetch_row() függvény nem nulla értékkel tér vissza. A ciklusmagban kiolvassuk az $egy_sor változóban tárolt elemeket és egy táblázat celláiként jelenítjük meg azokat a böngészőben. Mindezt az alábbi kódrészlet tükrözi, melynek teljes példaprogramja a mellékelt CD wosportable\www\diplomamunka\php\peldak\src könyvtárában, program_17_src.php néven található. $eredmeny = mysql_query("select * FROM adatok"); $sorok_szama = mysql_num_rows($eredmeny); print "Jelenleg $sorok_szama sor van a táblában"; print "<table border=1>"; while ($egy_sor = mysql_fetch_row($eredmeny)) { print "<tr>"; foreach ($egy_sor as $mezo) print "<td>$mezo</td>"; print "</tr>"; } print "</table>"; Az adatokat az UPDATE utasítással frissíthetjük, amelyet természetesen a mysql_query() függvénnyel kell átadnunk az adatbázis kiszolgálójának. A megváltozott sorok számát a mysql_affected_rows() függvénnyel kérdezhetjük le, amelynek szükség szerint egy kapcsolatazonosítót kell átadnunk. A mysql_affected_rows() függvényt bármely olyan SQL lekérdezés után használhatjuk, amely feltehetően módosított egy vagy több sort az adattáblában. A kapcsolódás és az adatbázis kiválasztása után megvizsgáljuk az $email és az $id változók meglétét. Ha mindent rendben találunk, összeállítjuk az SQL utasítást, amely a $email változó értékének megfelelően frissíti azt a sort, ahol az id mező tartalma megegyezik az $id változó értékével. Ha nem létező id értékre hivatkozunk vagy a kérdéses sorban a $email változó értéke megegyezik az email mező tartalmával, nem kapunk hibaüzenetet, de a mysql_affected_rows() függvény visszatérési értéke nulla lesz. A módosított sorok számát kiírjuk a böngészőbe. A karbantartó számára készítünk egy HTML űrlapot, amelyen keresztül elvégezheti a változtatásokat. Ehhez ismét a mysql_query() függvényt kell használnunk: lekérdezzük az id és email oszlopok összes elemét és beillesztjük azokat egy HTML select listába. A 20
karbantartó ezáltal egy lenyíló menüből választhatja ki, melyik bejegyzést kívánja módosítani. Ha a karbantartó már elküldte egyszer az űrlapot, akkor az utoljára hivatkozott azonositó érték mellé a selected módosítót is kitesszük, így a módosítások azonnal látszódni fognak a menüben. [3] Mindennek lényegi részét az alábbi utasítássorozat valósítja meg: if (isset($tartomany) && isset($azonosito)) { $parancs = "UPDATE adatok SET nev = '$nev' WHERE id=$id"; $eredmeny = mysql_query($parancs); } if (!$eredmeny) die ("Nem sikerült a módosítás: ".mysql_error()); print "A tábla módosítva, ".mysql_affected_rows(). "sor változott!"; <form action="<? print $PHP_SELF?>" method="post"> <select name="id"> <??> $eredmeny = mysql_query("select nev, id FROM adatok"); while ($egy_sor = mysql_fetch_object($eredmeny)) { print "<option value=\"$egy_sor->id\""; if (isset($id) && $id == $egy_sor->id) print " selected"; print "> $egy_sor->nev\n"; } mysql_close($kapcsolat); </select> <input type="text" name="nev " size="25"><br><br> <input type="submit" value="ok"> </form> Az ehhez kapcsolódó teljes példaprogam megtalálható a mellékelt CD wosportable\www\diplomamunka\php\peldak\src könyvtárában program_18_src.php néven, illetve tesztelhető a mellékelt alkalmazás PHP menüpont Adatbáziskezelés-MySQL\Adatok frissítése linkje alatt. 21
2. A MySQL adatbázis-kezelő rendszer 2. 1. Néhány szó a MySQL-ről 2. 1. 1. A relációs adatbázis-kezelő rendszer (RDBMS) A relációs adatbázis olyan sorokból és oszlopokból álló táblák együttese, amelyek között bizonyos oszlopaikban lévő értékek alapján meghatározott kapcsolatrendszer áll fenn. A relációs adatbáziskezelő-rendszer komponensei az adatbázisok, táblák, ezen belül adatoszlopok, adatsorok. A táblák kulcsok segítségével kapcsolódnak egymáshoz. A nagy, ismétlődő adatok egyvelegét tartalmazó táblák helyett, egymással megfelelő kapcsolatban álló, kisebb táblák használata segít az alkalmazás egyszerűsítésében és az adatok átláthatóságának, összefüggőségének megőrzésében. 2. 1. 2. Mi a MySQL? A MySQL a világon széles körben használt nyílt forráskódú, relációs adatbázis-kezelő rendszer. Főbb jellemzői a gyorsaság, a platformfüggetlenség és a költséghatékonyság. Nemcsak tárolja adatainkat, hanem egységes egészként kezeli őket, valamint lehetőséget ad felhasználói jogosultságok beállítására, naplózza az egyes felhasználók tevékenységeit. A legtöbb nyelv, mint pl. a PHP, a C, illetve a C++, a Java, a Python alkalmas arra, hogy felhasználói felületet írjanak hozzá. Minden MySQL-nek kiadott parancs az SQL nyelv szabályait követi. A PHP parancsnyelv egész sereg függvénnyel rendelkezik a MySQL-lel való használathoz, ezeket alkalmazzuk a kapcsolódáshoz és a lekérdezések futtatásához. 2. 2. A MySQL alkotóelemei Az adatbázis alapvető szerkezeti elemei a táblák, mezők, rekordok, kulcsok és indexek. A tábla az adatbázis legnagyobb alkotórésze. Létrehozási sorrendben a második, közvetlenül az adatbázis létrehozása után kerül rá sor. Ha egy táblát létrehozunk, törölhetjük 22
is, illetve módunkban áll lekérdező parancsokkal megváltoztatni a tábla felépítését. Mivel a tábla jelenti az adatok tároló helyét, törlése a benne lévő adatok elvesztésével jár. Ugyanígy a tábla szerkezetének megváltoztatása is hatással van a benne tárolt adatokra. A mezők adnak szerkezetet egy táblának és biztosítanak helyet az adatok tárolására. A táblázatkezelők példáját használva, a mező sok mindenben hasonlít az ott használt oszlopokra. A mezők és a táblák létrehozása egy időben zajlik. Valójában a mezők meghatározása a tábla létrehozásának legfontosabb része. Amikor a táblában használni kívánt mezőket megadjuk, két dolgot kell meghatároznunk: a mező típusát, valamint a hosszát. A mező típusa közvetlen kapcsolatban áll annak az adatnak a típusával, amit tárolni szeretnénk az adott mezőben. A mezők tulajdonságainak helyes megválasztása kiemelkedően fontos a megfelelő adatbázisszerkezet létrehozása szempontjából. A rekord egy bejegyzés a táblában. Ismét élve a táblázatkezelőben előforduló táblázatok hasonlatával, a rekord a táblázatban lévő sort jelenti minden oszlopban (mezőben) egy-egy bejegyzéssel. A rekordok lehetnek teljesen kitöltöttek (ekkor minden mező ki van töltve a megfelelő adattal) vagy kitöltetlenek. A kitöltetlen rekord nem feltétlenül jelenti, hogy a rekord üres. A tábla mezőinek típusmeghatározásaitól függően alapértelmezett értékeket adhatunk a rekord üres mezőinek. A mező- (vagy oszlop) típusokat, más szóval adattípusoknak is szokás nevezni, mert ezek egyben annak az adatnak a típusát is jelentik, amit tárolni fogunk az adott mezőben. A MySQL számos adattípust használ, ezeket három nagy csoportba oszthatjuk: numerikus, dátum és idő, valamint karakterlánc-típusok. A leggyakrabban használt adattípusok az INT (normál méretű egész szám, amiben ha használunk előjeleket, akkor -2147483-től 2147483- ig, ha nem használunk előjeleket 0-tól 4294967295-ig terjedhet), a DATE (dátum tárolására alkalmas a következő formában: ÉÉÉÉ-HH-NN, 1000-01-01 és 9999-12-31 közötti értékekkel) és a VARCHAR (1 és 255 közötti eltérő karakterhossz érhető el, ahol kötelező megadni a használni kívánt karakterek számát.) A kulcsok MySQL-tábláink és rekordjaink nagyon hatékony elemei. A táblák összekapcsolásához, illetőleg tételek egyértelmű azonosításhoz használunk kulcsokat. Megkülönböztetünk elsődleges (primary), egyedi (unique) és külső (foreign) kulcsokat. Az elsődleges kulcsként megjelölt mező egyedi értéket tartalmaz. Jelentősége abban áll, hogy összekötő elemként szolgál egy vagy több tábla között. Egy tábla csak egy elsődleges kulccsal rendelkezhet. Egyedi kulcsként megjelölt mező értékei szintén egyediek, azonban egy tábla több egyedi kulccsal is rendelkezhet, ugyanis jelen esetben nem az összekötő szerep a mérvadó, 23
hanem az, hogy az adott mező rekordjai szigorúan eltérőek legyenek. Például, ha egy szaküzlet eladandó áruinak nyilvántartását szeretnénk megvalósítani, eltérő tételeink lesznek. A nyilvántartás minden tételének rendelkeznie kell egy tételszámmal és minden ilyen tételazonosítónak egyedinek kell lennie. A tábla létrehozását követően, a tételszám mezőt egyedi kulcsként célszerű meghatározni. Külső kulcsként megjelölt mező olyan attribútum, mely egy másik entitásban elsődleges kulcsként szerepel. Relációk összekapcsolásánál van jelentősége. Az indexek meggyorsítják az adatok keresését. Amikor egy táblában egy mezőt elsődleges kulcsként definiálunk, a MySQL automatikusan hozzáadja a táblához az indexet. Lehetőségünk nyílik további indexek meghatározására is, amennyiben azt szeretnénk, hogy egy másik mező vagy több mező együttese szerint is indexelve legyen a tábla. Amikor az adatbázis által indexelt rekordokat válogatunk ki, a lekérdezés sokkal gyorsabb, az eredményt hamarabb kapjuk meg, mintha ugyanezt egy nem indexelt táblán tennénk. Ezzel szemben, amikor egy indexelt táblába szúrunk be egy rekordot, a művelet lassabb, mint egy indexeletlen tábla esetén. A tábláinkon gyakrabban végzett műveletek határozzák meg, mikor érdemes több indexet létrehoznunk, és mikor jobb beérni kevesebbel. A MySQL 5-ös verziójában már adott a lehetőség nézetek (view), tárolt eljárások és triggerek készítésére is. Egy ilyen nézet nem más, mint egy SQL lekérdezés által reprezentált adathalmaz, amelyet úgy érhetünk el, mintha az egy önálló tábla volna. Egy tárolt eljárás olyan SQL nyelven írt parancsok összessége, amelyet az adatbázis kiszolgálón rögzítünk, s utána a programozásban használatos módon meghívhatjuk. Ekkor elvégzi azokat az SQL utasításokat, amelyeket az eljárás törzsében meghatároztunk. Néhány bővítménynek köszönhetően tehát gyakorlatilag programozhatunk az adatbázis-kezelő berkein belül. A triggerek olyan speciális tárolt eljárások, amelyek valamilyen esemény (INSERT, UPDATE, DELETE) esemény során hívódnak meg automatikusan. A trigger egy adott táblához van kötve, és az arra a táblára vonatkozó, előre megadott művelet során hajtódik végre. Általában adatbázisba írás előtti ellenőrzésre, írás utáni számított érték kiszámítására, törlés előtti adatok bizonyos részeinek rögzítésére, stb. használhatjuk. [4] 24
3. Az elkészített alkalmazás környezetének telepítése A PHP fájlokból álló komplex rendszert PHP alkalmazásnak nevezzük. Amennyiben gépünkön üzemel Apache és MySQL szerver, a fájlok megfelelő helyre való másolásával, néhány egyszerűbb konfigurációs lépéssel és egy böngésző segítségével életre kelthetjük a PHP + MySQL alkalmazásunkat. Megfelelő hely alatt egy a webkiszolgálónk számára látható és elérhető könyvtárat értünk. Például a korábban preferált WOS Portable csomag számára a www könyvtár a mérvadó. Az elkészített alkalmazás telepítésére a melléklet CD-n biztosítva van egy install.exe nevű telepítőprogram, mely az InstallCreator szoftverrel készült. [5] Indításával telepítésre kerül a már említett, CH Software által fejlesztett, Apache-al, PHP-vel és MySQL-el felvértezett WOS Portable ingyenes programcsomag, melyben integrálva szerepel a diplomamunka projektként elkészített PHP + MySQL alkalmazás. 3.1. ábra: Az alkalmazás telepítőprogramja Amennyiben gépünkön, szerverünkön már üzemel Apache, és MySQL kiszolgáló, tehát biztosított a PHP értelmező is, és csak az alkalmazás forrására tartunk igényt, kimásolhatjuk a mellékelt CD wosportable\www\diplomamunka könyvtárából, melyben az alkalmazással kapcsolatos összes forráskód megtalálható. Az alkalmazás indítása előtt a rendszer számára be kell állítani a MySQL kiszolgálót érintő kommunikációs csatornát. Meg kell adni a kiszolgáló nevét, a felhasználót és a jelszót. Lokális gépre telepítve, elég lazák a megkötések. Alapértelmezett kiszolgáló a localhost, felhasználó a user, valamint jelszó nincs definiálva. Mindezt a wosportable\www\diplomamunka\config.php fájlban ellenőrizhetjük és szükség esetén itt konfigurálhatunk. Az alkalmazás úgy lett tervezve, hogy a kapcsolódási adatokat kizárólag ebből a fájlból veszi, tehát elegendő egy helyen módosítani, ha például szerver oldalon telepítünk és más csatlakozási paramétereket szeretnénk megadni. 25
A config.php fájl $mysql_hostname, $mysql_username és $mysql_password komponensein kívül lehetőségünk van még a kidolgozott feladatok megoldásait feloldó jelszó megváltoztatására is. Ezt ugyanitt, a $solution_password komponens értékének megváltoztatásával tehetjük meg. Az alkalmazás az index.html lappal indul. A fájl kiterjesztés azért html és nem php, mert ő csak a szükséges php modulokat aktiválja, maga az index lap nem tartalmaz php kódot, ezért hatékonysági és performanciai szempontokat figyelembe véve felesleges php kiterjesztéssel ellátni és php értelemzővel lassítani a betöltést. 4. A mintaadatbázis bemutatása A diplomamunkához tartozó mintaadatbázis a gyakorlati életből merít. Cél a közérthetőség, átláthatóság, mindemellett a kellő komplexitás, és alkalmasság ahhoz, hogy bővíteni tudjuk, illetőleg, hogy megfelelő nehézségű feladatokat prezentálni tudjunk rajta. Az adatbázis eredeti verziója Oracle rendszerben készült [6], így feladat a MySQL alapokra való átültetés. Egy partner- illetve számlanyilvántartó adatbázismodellt valósít meg, mely egy vállalkozás rendszerének alapja lehet. Az adatbázis teszt néven fut és tizenegy táblából épül fel. Tartalmaz elsődleges- és külső kulcsokat, valamint triggereket is. 4. 1. A mintaadatbázis felépítése A mintaadatbázis partnertípúsai lehetnek munkatársak (M), vevők (V), szállítók (S) és bankok (B). A bank típus bankszámláink megfelelő módon történő tárolásáért, struktúrába szervezéséért felel. A partner táblában csupán két adatot tárolunk: a partner_id-t (ami egy egyedi azonosító és egyben elsődleges kulcsa is a táblának), valamint a partner típusát, ami egy karakter (M, V, S ill. B). Erre a felépítésre azért van szükség, hogy csupán a partner_id alapján meg tudjuk határozni a típust is, és így tudni fogjuk, hogy a specifikus partneradatokat mely táblában kell keresnünk. A vevo, szallito, munkatars, bank táblák elsődleges kulcsa a partner_id, ami egyben külső kulcs is a partner táblára vonatkozóan. 26
4.1.1. ábra: A mintaadtabázis modellje A munkatars táblában munkatárs típusú partnereink adatait tartjuk nyilván. Az attribútumok elnevezései magukért beszélnek. Tároljuk a vezetéknevet, keresztnevet, telefonszámot, a munkaviszony kezdetének dátumát, a munkabért, a pozíciót és az adott osztályt, ahol a munkatárs dolgozik. A munkatars tábla AFTER DELETE triggere törléskor a partner táblából is kiiktatja az adott partner_id bejegyzését: DROP TRIGGER IF EXISTS TAD_MUNKATARS; // CREATE TRIGGER TAD_MUNKATARS AFTER DELETE ON munkatars FOR EACH ROW BEGIN DELETE FROM partner WHERE partner.partner_id=old.partner_id; END // A fenti trigger teljesen hasonló módon a vevo és szallito partnertípúsnál is definiálva lett. A triggerek forráskódja elérhető a mellékelt CD wosportable\www\diplomamunka\minta\db könyvtárában, triggers.sql fájlnév alatt. 27
A vevo és a szallito táblák esetén az azokhoz kapcsolódó BEFORE INSERT triggerek azt is leellenőrzik, hogy NULL értékűek-e a kiallt_szamla_db és kiallt_szamla_ertek mezők. Amennyiben igen, 0-t rögzít NULL helyett. Ennek oka azon egyszerű szabályszerűség, mely szerint a NULL értékhez bármilyen számot hozzáadva NULL értéket kapunk. Amennyiben tehát nem tennénk meg a fenti lépést, a táblánkban ezen attribútumok NULL értékek maradnának. A két trigger csak a táblanevekben tér el, magjuk azonos. Az alábbiakban a vevo táblára vonatkozó triggert szemléltetjük. DROP TRIGGER IF EXISTS TBI_VEVO; // CREATE TRIGGER TBI_VEVO BEFORE INSERT ON vevo FOR EACH ROW BEGIN IF new.kiallt_szamlak_db IS NULL THEN UPDATE vevo v SET new.kiallt_szamlak_db=0 WHERE v.partner_id=new.partner_id; END IF; END // IF new.kiallt_szamlak_ertek IS NULL THEN UPDATE vevo v SET new.kiallt_szamlak_ertek=0 WHERE v.partner_id=new.partner_id; END IF; A vevo és szallito entitásokat hasonló felépítésük következtében egyszerre kerülnek bemutatásra. A szallito entitás mindössze abban különbözik a vevo-től, hogy van egy plusz adoszam attribútuma is. A kiallt_szamlak_db és kiallt_szamlak_ertek mezőkben az adott partnerhez kapcsolódó számlák darabszámát és összértékét tartjuk nyilván. Ezen mezők töltését a szamlak táblához kapcsolt triggerek segítségével a MySQL rendszer végzi: amennyiben rögzítünk (INSERT), illetve módosítunk (UPDATE) egy számlát, a partner_id alapján a trigger megkeresi, hogy az vevő illetve szállító típusú, majd a megfelelő entitásban (vevo vagy szallito tábla) update-eli a partner_id-hez kapcsolódó rekordban a kiallt_szamlak_db és a kiallt_szamlak_ertek attribútum értékét (a kiállt számlák értékét növeljük a számla összegével (szamlak.osszeg), illetve a darabszámot növeljük eggyel. A számla rögzítésénél aktiválódó triggert (BEFORE INSERT) mutatjuk be, a számlák módosításánál életbe lépő trigger (BEFORE UPDATE) hasonló struktúrájú, forráskódja szintén a kapcsolódó CD-melléklet wosportable\www\diplomamunka\minta\db könyvtárában triggers.sql fájlnév alatt található meg. 28
DROP TRIGGER IF EXISTS TBI_SZAMLAK; // CREATE TRIGGER TBI_SZAMLAK BEFORE INSERT ON szamlak FOR EACH ROW BEGIN DECLARE f_tipus CHAR(1); SELECT p.tipus INTO f_tipus FROM partner p WHERE p.partner_id=new.partner_id; IF f_tipus='v' THEN UPDATE vevo v SET v.kiallt_szamlak_db=v.kiallt_szamlak_db+1, v.kiallt_szamlak_ertek=v.kiallt_szamlak_ertek+new.osszeg WHERE v.partner_id=new.partner_id; UPDATE bankszamla b SET b.osszeg=b.osszeg+new.osszeg WHERE b.bankszamlaszam=new.bankszamlaszam; END IF; IF f_tipus='s' THEN UPDATE szallito s SET s.kiallt_szamlak_db=s.kiallt_szamlak_db+1, s.kiallt_szamlak_ertek=s.kiallt_szamlak_ertek+new.osszeg WHERE s.partner_id=new.partner_id; UPDATE bankszamla b SET b.osszeg=b.osszeg+new.osszeg WHERE b.bankszamlaszam=new.bankszamlaszam; END IF; END // A vevo és szallito entitások harmadik bemutatást igénylő mezője a jogi_forma_kod, amely a jogi_forma táblára hivatkozó külső kulcs. A jogi_forma táblában a vevők és szállítók lehetséges jogi formáit soroljuk fel. Erre a megoldásra azért van szükség, hogy csak meghatározott értékek közül választhassunk, és ki tudjuk szűrni a redundanciát, vagyis jelen esetben az eltérő jogi forma megnevezéseket, mint pl.: bt, BT, Bt. A bank tábla felépítése nem igényel további magyarázatot. Ehhez az entitáshoz kapcsolódik a bankszamla entitás a partner_id alapján, ami külső kulcs a bankszamla táblában. A tábla elsődleges kulcsa a bankszámlaszám (bankszamlaszam). A fent bemutatott TBI_SZAMLAK triggerből már látható volt, hogy ebben a táblában sem kell az összeg mezőt töltenünk, azt tölti a trigger a számlamozgások alapján. A cimek entitásban a partner_id-hez kapcsolódó címet visszük fel. Egy partnernek lehet több címe is, azonban mindig csak egy (az utoljára rögzített) lesz aktív is (az aktív attribútum értéke minden partner_id esetében egyszer lehet csak I, minden más esetben 29
H ). Ezen táblához az irszam attribútumon keresztül kapcsolódik az irsz_megye tábla, melyben hozzákereshetjük az adott irányítószámhoz a település nevét és a megyét. Ebben az esetben egy a táblához kapcsolódó CHECK figyeli, hogy csak konzisztens megyeneveket lehessen felvinni: ALTER TABLE irsz_megye ADD CONSTRAINT chk_megye CHECK (megye IN ('Bács-Kiskun','Baranya','Békés', 'Borsod-Abaúj-Zemplén','Csongrád','Fejér', 'Gyor-Moson-Sopron','Hajdú-Bihar','Heves','Jász-Nagykun-Szolnok', 'Komárom-Esztergom','Nógrád','Pest','Somogy', 'Szabolcs-Szatmár-Bereg','Tolna','Vas','Veszprém','Zala')); A tulajdonos entitás a vevőink és szállítóink között kialakult tulajdoni viszonyok ábrázolására használható. A partner_id oszlopban a leány, míg a partner_id_tulaj oszlopban az anyavállalat id-je kell, hogy szerepeljen, a harmadik oszlopban pedig a tulajdoni hányad, (tulajodonosi_hanyad) amely értéke nulla és száz közé esik. A szamlak tábla elsődleges kulcsa a számlaszám (szamlaszam), emellett két külső kulccsal is rendelkezik: a partner_id a partner entitásra, a bankszamlaszam a bankszamla entitásra hivatkozik. 4. 2. A mintaadatbázis telepítése A mintaadatbázis telepítéséért felelős scriptek a mellékelt CD wosportable\www\diplomamunka\minta\db könyvtárában találhatóak. A teszt.sql magát a mintaadatbázist hozza létre teszt néven, a feltolt.sql adatokkal tölti fel az adatbázist és létrehozza a szükséges megszorításokat, kulcsokat, relációkat, a triggers.sql pedig a szükséges triggereket helyezi el az adott táblákon. A későbbiekben látni fogjuk, miként van lehetőség a mintaadatbázis manipulálására. Amennyiben törölni szeretnénk a már manipulált, általunk módosított adatbázist, a drop.sql scriptet kell aktiválnunk, és tiszta lappal indíthatunk. Mindezek vezérlésére egy egyedi felület áll rendelkezésre a mellékelt alkalmazás MINTA szekciójának Mintaadatbázis\Management menüpontja alatt. A feladatok egy különálló adatbázis az eredmenyek táblával. Erre azért van szükség, hogy letároljuk az egyes felhasználók által megoldott feladatokat és az elért teljesítményt. A későbbiek folyamán részletesebb bemutatásra kerül. 30
4. 3. Szabad navigáció A mellékelt program MINTA szekciójának Mintaadatbázis\Térkép menüpontja alatt található a mintaadatbázis felépítésének térképe, mely segít eligazodni az adatbázis útvesztőiben. Szemlélteti a kulcsokat, adattípusokat, a táblák közötti prioritást, az adatbázis teljes struktúráját. A mellékelt program MINTA szekció Mintaadatbázis\Szabad navigáció menüpontja arra ad lehetőséget, hogy a mintaadatbázist szabadon manipuláljuk. Táblánként beszúrhatunk, módosíthatunk, illetőleg törölhetünk adatokat. Minden egyes adatmanipuláció során azonban ügyelnünk kell arra, hogy ne ütközzünk ellentmondásba, illetőleg a külső kulcsok által létrehozott kapcsolati feltételeknek eleget tegyünk. Az insert gomb mindenkor aktív, miután a beviteli mezők kitöltésre kerültek vele lehet jóváhagyni a beszúrást. Minden rekord végén szerepel egy delete gomb, mely a törlésért felel. Az update gomb a módosított rekordok érvényesítését végzi. Csak akkor aktív, ha van módosítható rekord a táblában. Az egyes rekordok módosítását a bal oldali radio gombok segítik. Aktiválva őket, az adott rekord tartalmát a rendszer a szerkesztésre alkalmas mezőkbe másolja (lásd 4.3.1. ábra). A táblák mindig friss, aktuális adatokat tartalmaznak, felületük dinamikusan programozott. A mezőnevek sötét alapszíne állandó, a táblák fejlécét emeli ki, míg az egymást követő rekordok színei váltakoznak. A halványszürke után egy picit sötétebb árnyalat következik, majd fordítva. Mindez az átláthatóbb adathalmazt és a kényelmesebb változáskövetést szolgálja. 4.3.1. ábra: Hatékony adatmódosítás radio gombbal 31
5. Kidolgozott gyakorlatok 5.1. A gyakorlatokhoz kapcsolódó interface ismertetése A mellékelt program GYAKORLAT szekciójában próbára tehetjük a PHP és SQL témakörhöz kapcsolódó ismereteinket. A szekció egy pontszámismertető és egy login részből áll. A pontszámismertető frame statikus, hogy mindenkkor tájékozódhassunk a megszabott ponthatárokról. Ezzel ellentétben a login modul dinamikusan kezeli a folyamatokat. A bejelentkezéshez meg kell adni egy egyedi azonosítót. Ezáltal kezeli a rendszer az egyes munkameneteket, ill. tartja nyilván a különböző felhasználók által megoldott feladatokat és elért pontszámokat. Bejelentkezéskor a rendszer a már korábban létrehozott feladatok adatbázis eredmenyek táblájába beszúr egy rekordot, mely tartalmazza a felhasználó egyedi azonosítóját, a tíz php, ill. a tíz sql feladat státuszát, valamint egy pontszam mezőt. Státusz alatt az egyes feladatok megoldott, illetve megoldásra váró állapota értendő. Kezdetben a feladatok mezőit egy N (nem) bejegyzéssel, a pontszam mezőt pedig nullával tölti fel a program, jelezve, hogy a feladatok még függőben vannak. Amint egy feladat megoldása egy adott felhasználó által sikeres, a program a megoldott feladat státuszát igenbe állítja úgy, hogy a sikeres megoldó megfelelő feladatánál egy I karakterre frissít az eredemenyek táblában, valamint a megoldott feladatra szabott pontértékkel növeli pontjait. 5.1.1. ábra: A feladatok adatbázis eredmenyek táblájának egyszerűsített szerkezete Az elért eredményekre vonatkozó Mutat nevű link egy a sum.php programkomponens által generált lapot hoz be, ahol az eredmenyek tábla aktuális állapotát láthatjuk, kizárólag a 32