Webtechnológia, előadásvázlat, 2007/08-II. félév
Adatbázis használata PHP-ből Adatbázis használata PHP-ből..........................................................................1 Nyílt forráskódú adatbázisok............................................................................................................1 A mysql függvények ........................................................................................................................2 A mysqli függvények .......................................................................................................................4 Bináris adatok adatbázisban való tárolása........................................................................................8 Adatbázis csatoló osztályok .............................................................................................................9 Esettanulmányok ..............................................................................................................................9
Nyílt forráskódú adatbázisok -MySQL, PostgreSQL, Mysqli -hogyan használjuk őket PHP-ből Az erőforrás (resource) egy olyan speciális PHP változó, ami egy külső erőforrásra tartalmaz referenciát vagy azonosítót. Erőforrás pl. egy állomány megnyitása után az állományra mutató szerkezet, az adatbázis kapcsolat, hálózati kapcsolat. Tehát az erőforrásokat speciális függvények hozzák létre és használják. -kapcsolatok általában TCP portokon keresztül: 3306 MySQL, 5432 PostgreSQL A PHP-ből egyszerű esetben az alábbi műveleteket kell elvégezni adatbázis használatakor: 1. az adatbázis kapcsolat megnyitása: eredménye egy erőforrás típusú változó, az adatbázis kapcsolat (connection) 2. a lekérdezés végrehajtása, SQL keresés esetében eredménye egy SQL válasz, amely a lekérdezett eredményt tartalmazza (resultset). 3. Az előbbiből kell ezután kiolvasni az eredmény sorait, ehhez a művelethez több függvény áll rendelkezésünkre. Kiolvasás után az eredmény sorait PHP tömbökbe olvassuk. 4. Ha feldolgoztuk az eredményt fel kell szabadítani a lefoglalt erőforrásokat. Minden egyes fázis után hibaellenőrzést kell végezni, és ha hiba adódik azt megfelelően kezelni kell. Perszisztens (állandó) adatbázis kapcsolatok -a PHP leellenőrizheti, hogy létezik e ugyanolyan tulajdonságú kapcsolat mielőtt újat nyitna, és ha igen, akkor felhasználja azt. Ezzel terhelést lehet levenni az adatbázisról, mivel nem kell újra és újra hitelesíteni a kapcsolatot. Ezt csak akkor használható, ha a PHP modulként fut. Hátránya a sok megnyitott kapcsolat által lefoglalt erőforrás. A maximálisan megnyitható kapcsolatok számát a php.ini illetve az adatbázis konfigurációs állományaiban lehet behatárolni. Függvénycsoportok: MySQL, MySQLi, Postgres, stb: gyakorlatilag minden fontosabb adatbázishoz 1
Webtechnológia, előadásvázlat, 2007/08-II. félév
találunk függvényeket.
A mysql függvények Ez a függvénycsoport a bevezetőben említett kétféle erőforrás típust használja, a kapcsolatot és a lekérdezési választ. Fontosabb függvények (részletesen PHP kézikönyv MySQL függvények fejezete): mysql_connect -- Kapcsolatot nyit meg egy MySQL szerverhez mysql_pconnect -- Perszisztens kapcsolatot nyit meg a MySQL szerverhez mysql_select_db -- Kiválaszt egy MySQL adatbázist mysql_create_db -- Létrehoz egy MySQL adatbázist mysql_error -- Az előző MySQL művelet hibaszövegét adja mysql_query -- MySQL kérést küld a szervernek mysql_affected_rows -- Az előző MySQL műveletben érintett sorok számát adja meg mysql_num_fields -- Az eredményben szereplő mezők számát adja mysql_num_rows -- Az eredményben szereplő sorok számát adja vissza. mysql_result -- Eredmény egy sorának lekérdezése mysql_fetch_array -- Kérés egy sorát adja vissza (tetszőleges) tömb formájában mysql_fetch_assoc -- Az eredmény egy sorát asszociatív tömbként adja vissza. mysql_fetch_field -- Eredményhalmaz egy oszlopáról ad információt objektum formájában mysql_fetch_row -- Az eredmény következő sorát adja vissza számmal indexelt tömb formájában Az SQL parancsokban felhasznált PHP változókat át kell futtatni olyan függvényeken amelyek kiszűrik az SQL kontroll karaktereket: mysql_escape_string -- Egy karakerláncban szereplő speciális karakterek értelmezését szünteti meg – de nem törődik a karakterkészlettel, elavult mysql_real_escape_string -- Levédi egy stringben a speciális karaktereket egy SQL lekérdezés számára, az átírt karakterek: \x00, \n, \r, \, ', " és \x1a. Használható erre még a következő két függvény is: addslashes() . Az eredmény mezőiről az alábbi függvényekkel lehet információt kérni: mysql_field_flags -- Adott eredmény adott mezejének flagjeit adja vissza. mysql_field_len -- A kérdezett mező hosszát adja vissza mysql_field_name -- Adott mező nevét adja vissza mysql_field_seek -- Az eredménymutatót a kívánt pozícióba mozgatja mysql_field_table -- Visszaadja annak a táblának a nevét, melyben a megadott mező található mysql_field_type -- Az eredmény adott mezejének típusát adja vissza Lezárásra használt függvények: mysql_free_result -- Felszabadítja az eredmény által lefoglalt memóriát mysql_close -- Lezár egy MySQL kapcsolatot 2
Webtechnológia, előadásvázlat, 2007/08-II. félév
Példa:
die(mysql_error());
/* a használt City tábla: +-------------+----------+------+-----+---------+----------------+ | ID | int(11) | NO | PRI | NULL | auto_increment | | Name | char(35) | NO | | | | | CountryCode | char(3) | NO | | | | | District | char(20) | NO | | | | | Population | int(11) | NO | | 0 | | +-------------+----------+------+-----+---------+----------------+ */ $rs = mysql_query ("select * from City order by Id limit 0,5") or die(mysql_error()); //egy mezo beolvasasa az eredmeny elso sorabol (0) //a mezo neve Name $f = mysql_result ($rs, 0, 'Name') or die(mysql_error()); print('
Az első sor Name oszlopa:' . $f); //egy sor beolvasasa asszociativ tombkent $a = mysql_fetch_assoc($rs); print '
a második sor tartalma'; print_array($a); //egy sor beolvasasa numerikus es asszociativ indexu tombkent $a = mysql_fetch_array($rs); print '
a harmadik sor tartalma - itt mindkét típusú indexre előállítja a tömböt'; print_array($a); //a tobbi sor beolvasasa numerikus indexu tomkbent print '
a maradék 2 sor tartalma'; while (list($id, $name, $distr, $pop) = mysql_fetch_row ($rs)) { print '
'.$id.' ' . $name . ' ' . $distr . ' ' . $pop; } //lezaras mysql_free_result($rs); mysql_close($conn); ?>
3
Webtechnológia, előadásvázlat, 2007/08-II. félév
A mysqli függvények -objektum orientált és procedurális változat is (részletesen PHP kézikönyv MySQLi függvények fejezete): A mysqli objektum Fontosabb osztály függvények: query – lefuttatja az SQL parancsot close – kapcsolatot zár connect – megnyitja a kapcsolatot info – kiírja az SQL parancs által érintett sorok számát A keresések az adatbázis oldalán vagy lokálisan puffereltek, és az alábbi konstansokkal lehet megadni a keresés módját: - MYSQLI_STORE_RESULT (kliens oldalon pufferelt) - MYSQLI_USE_RESULT(adatbázis oldalán pufferelt), implicit érték: MYSQLI_STORE_RESULT rollback – rollback parancsot ad ki select_db – kiválasztja az adatbázist prepare – lekérdezési tervet készít elő, eredménye egy lekérdezési terv objektum. Osztálytulajdonságok: affected_rows – hány sor érintett az UPDATE vagy INSERT parancs errno – hibakód visszatérítése error – a szerver hibaüzenetét adja vissza field_count – hány oszlop van a lekérdezés eredményében num_rows – hány sor van a lekérdezés eredményében A mysqli_result objektum A lekérdezés eredményét tartalmazza Fontosabb osztály függvények: close – lezárja az eredményt data_seek – elmozdítja az eredmény mutatóját fetch_array – asszociatív és numerikus indexű tömbbe olvassa az eredményt fetch_assoc - asszociatív indexű tömbbe olvassa az eredményt fetch_row - numerikus indexű tömbbe olvassa az eredményt free_result – felszabadítja az eredmény által lefoglalt memóriát Osztálytulajdonságok: num_rows – hány sor van az eredményben type – az eredmény típusát adja vissza MYSQLI_STORE_RESULT (or MYSQLI_USE_RESULT) 4
Webtechnológia, előadásvázlat, 2007/08-II. félév
A mysqli_stmt objektum – a lekérdezési tervet tartalmazza Fontosabb osztály függvények: bind_param – paramétereket köt a tervhez bind_result – változókat köt az eredményhez close – lezárja a lekérdezési tervet execute – végrehajtja a tervet fetch – lekéri a lekérdezési terv eredményét a változókba free_result – felszabadítja az eredmény által foglalt memóriát prepare – SQL lekérdezést készít elő send_long_data – darabokban küld adatokat a lekérdezési tervnek, hogy egy darab ne haladja meg az adatbázis kapcsolat csomagméretét Értékek (osztálytulajdonságok) affected_rows – hány sort érint az SQL utasítás (INSERT, UPDATE) num_rows – hány sor van az eredményben Egyszerű lekérdezés példa
egy Internetrol jovo valtozo
$pricelimit = mysql_real_escape_string($pricelimit); $q = "SELECT author, title , price FROM books WHERE price < $pricelimit ORDER BY price limit 0,10" ; //a kapcsolat letrehozasa, hiba eseten leallas $conn = new mysqli ('localhost', 'user', 'pass'); //hiba eseten leallas if (!$conn) die ("Nem lehet kapcsolódni az adatbázishoz"); //adatbazis kivalasztas if ( ! $conn->select_db('lszabo') ) die (mysqli_error($conn)); //a kereses vegrehajtasa if (! ($res=$conn->query($q)))
5
Webtechnológia, előadásvázlat, 2007/08-II. félév die (mysqli_error($conn)); echo 'Keresés eredménye'; echo '
Sorok száma: ' . $res->num_rows . '
'; //a sorok kiolvasasa asszociativ tombbe while ( $a = $res->fetch_assoc()) { echo $a['author'] . ' : ' , $a['title'] . ' Ár:' . $a['price'] . ' RON
'; } //takarítás $res->free(); $conn->close(); ?>
Lekérdezési tervek használata: -előnye, hogy a lekérdezést egyszer elemzi az adatbázis elemzője (parser) és lekérdezés tervezője (planner) -ha többször kell ismételni ugyanazt az SQL-t akkor nagyon előnyös -mire használható: INSERT, REPLACE, UPDATE, DELETE, CREATE TABLE, SELECT (az úgynevezett adatkezelő – DML - parancsokhoz) -használatánál az alábbi menetet kell követni (zárójelben a megfelelő függvénynevek): 1. előkészítés (prepare) 2. paraméterek hozzárendelése a tervhez (bind_param) 3 az SQL lefuttattatása (execute) 4 változók hozzárendelése az eredményhez (bind_result) 5 eredmény beolvasása (fetch) Példa: select_db('lszabo') ) die (mysqli_error($conn)); //1. a terv elokeszitese
6
Webtechnológia, előadásvázlat, 2007/08-II. félév //a kérdőjelek helyén vannak a paraméterek $stmt = $conn->prepare ( 'SELECT author, title FROM books where price < ? and weight > ?' ); //2. a valtozok hozzarendelese a tervhez $stmt->bind_param('dd',$price,$weight); //itt adunk erteket a valtozoknak a a lekerdezeshez $price=15.; //RON $weight=300.; //g //3. a lekerdezes vegrehajtasa if (!$stmt->execute()) die ("Sikertelen query."); //4. az eredmeny hozzarendelese valtozokhoz $stmt->bind_result($author, $title); echo "Nagy súlyú (>$weight g) és olcsó könyvek (< $price RON)
"; //5. az eredmeny beolvasasa a valtozokba while($stmt->fetch()) { echo "
" . $author . " : " . $title; } //a lekerdezest ismetelhetjuk //ismetles, uj bemeneti valtozok $price=15.; //RON $weight=400.; //g if (!$stmt->execute()) die ("Sikertelen query."); echo "
Nagyobb súlyú (>$weight g) és olcsó könyvek (< $price RON)
"; // a masodik kereses beolvasasa while($stmt->fetch()) { echo "
" . $author . " : " . $title; } //ismetles $price=15.; //RON $weight=450.; //g if (!$stmt->execute()) die ("Sikertelen query."); echo "
Nagyon nagy súlyú (>$weight g) és olcsó könyvek (< $price RON)
"; while($stmt->fetch()) { echo "
" . $author . " : " . $title; }
7
Webtechnológia, előadásvázlat, 2007/08-II. félév
$conn->close(); ?>
Bináris adatok adatbázisban való tárolása -képek vagy mérési adatok -a bináris adatokat az adatbázisok gyakorlatilag sztringként kezelik (text típusként is deklarálhatóak) -méretek amiket tárolni lehet pl. a MySQL-nél: -a TEXT típusokban szöveget, a BLOB típusokban bináris adatot tárol MySQL típus
Méret
TINYBLOB vagy TINYTEXT
0 .. 256 byte
MEDIMBLOB vagy MEDIUMTEXT
0 .. 65535 byte (65k)
BLOB vagy TEXT
0 .. 16.777.215 byte (17 M)
LONGTEXT vagy LONGBLOG 0 .. 4.294.967.295 (4 GB) -hasonló típusok más adatbázisoknál is megtalálhatóak, a méreteket ellenőrizni kell Az adatbázisba írás: -mysql függvények esetében rendes INSERT, SELECT és UPDATE utasításokkal ahol a bináris mezőt értékét úgy kell megadni mint egy sztringet -ezért beíráskor ha $data a mező értéke az: $data =
addslashes ($data);
függvényt kell használni. A mysqli függvények esetében lehetséges a bináris adatok részletekben való átvitele lekérdezési terv és a mysqli_send_long_data () függvény használatával. A PHP és MySQL közti átviteli kapcsolat csomagmérete általában korlátozva van, ezért ez utóbbi megoldás minden szempontból előnyös. A MySQL implicit átviteli csomagmérete 1 MB, a konfigurációs változó neve max_allowed_packet . Ezt a konfigurációs állományban (my.cnf) a következő sorral lehet módosítani: [mysqld] max_allowed_packet=16M
8
Webtechnológia, előadásvázlat, 2007/08-II. félév
Két példát adunk, az első az egyszerű mysql interfésszel, a második a mysqli -vel ír be bináris adatot. A példa állományok a honlapon a példák között: blob_simple.php (mysql) és blob.php (mysqli és send_long_data() ).
Adatbázis csatoló osztályok példák: mysql függvényekre: Db , MyDb mysqli függvényekre: Dbi, MyDbi -a különböző programozási interfészek általában tartalmaznak ilyen osztályt -ezek legtöbb esetben az általános, adatbázistól független csatolást is megoldják
Esettanulmányok 1. Azok az esetek amikor egy adatbázis tábla egyetlen sora ábrázol egy alkalmazásban használt objektumot (aktív rekord). Példa: felhasználó kezelése. Példa osztály: User, állomány: user.php -létrehozás, insert/update/select függvények -szesszióba való mentés 2. Azok az esetek amikor az alkalmazás egy adatbázis táblában ábrázolt objektumokat járja végig. Példa osztály: Browser, állomány browser.php -lapozás megoldása -böngészést segítő függvények -szesszióba való mentés Függetleníteni kell az alkalmazások három rétegét: -az objektumaink adatbázisban való ábrázolását -a feldolgozást vagy alkalmazáslogikát -a megjelenítést A Browser osztály az adatbázis elérést a Db osztályra bízza, a megjelenítéshez pedig külön megjelenítő osztályt lehet írni (az osztály __toString() és to_html() metódusai csak a tesztekhez szükséges megjelenítésre jók).
9