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

SKRIPTA IZ PREDMETA INTERNET TEHNOLOGIJE

Rad sa bazama podataka u PHP-u

SADRAJ
1 2 UVOD.............................................................................................................................3 PHP i rad sa bazama podataka......................................................................................5 2.1 PhpMyAdmin............................................................................................................6 Kreiranje nove baze..........................................................................................7 Korienje SQL naredbi za kreiranje baze......................................................11 Izvoz podataka................................................................................................11 Uvoz podataka................................................................................................12 2.1.1 2.1.2 2.1.3 2.1.4 2.2 2.3 3 3.1 3.2 3.3 3.4 3.5 4 4.1 4.2 4.3 4.4 4.5 4.6 4.7 5 6

PHP, MySQL i korienje naih slova....................................................................13 Pregled najee korienih SQL upita..................................................................14 Konekcija na MySql server.....................................................................................16 Ubacivanje podataka u bazu (naredba INSERT INTO)..........................................18 itanje podataka iz baze (naredba SELECT).........................................................20 Brisanje podataka (naredba DELETE)...................................................................23 Izmena postojeih podataka (naredba UPDATE)...................................................26 Konekcija na MySql server.....................................................................................35 Ubacivanje podataka u bazu (naredba INSERT INTO)..........................................36 itanje podataka iz baze (naredba SELECT).........................................................38 Brisanje podataka (naredba DELETE)...................................................................40 Izmena postojeih podataka (naredba UPDATE)...................................................43 Rad sa transakcijama.............................................................................................51 Pripremljeni upiti.....................................................................................................53

Ekstenzija php_mysql...................................................................................................16

Ekstenzija php_mysqli..................................................................................................35

Ekstenzija php_pdo......................................................................................................55 PHP i ODBC.................................................................................................................60

Indeks primera......................................................................................................................61 Indeks tabela........................................................................................................................62 Indeks slika..........................................................................................................................62 Indeks slika

1 UVOD
Troslojna arhitektura predstavlja tip klijent-server arhitekture u kojoj su korisniki interfejs, procesi poslovne logike i pristup podacima, projektovani i upravljani kao nezavisni moduli. Osnovne komponente (slojevi) ove arhitekture su: Klijentski (prezentacioni) sloj Sloj poslovne (aplikativne) logike Sloj podataka

Slika 1: Troslojna arhitektura web aplikacija

Preko PHP-a kao skriptnog jezika na serverskoj strani, realizuje se najvei deo poslovne logike aplikacije. Podaci vezani za aplikaciju se mogu skladititi u obinom tekstualnom fajlu, iz kojeg se pomou PHP mogu itati i upisivati. Meutim, ako je u pitanju ozbiljnija aplikacija, neophodno je koristiti relacione baze podataka. Najee, ovo znai da e se korsititi server baze podataka koji podraava SQL (Structured Query Language) specifikaciju. SQL je standardni programski jezik za pristup i manipulaciju podacima iz relacionih baza podataka i podran je od strane svih servera relacionih baza podataka. U relacionim bazama podaci su skladiteni preko niza tabela. Svaka tabela sadri kolone koje opsiuju atribute podataka, a svaki red je instanca podataka. Relational Data Base Management Systems (RDBMS), odnosno sistemi za upravljanje relacionim bazama podataka su se u praksi pokazali kao najbolji nain upravljanja podacima. 3

Strane kreirane u nekom skriptnom jeziku serverske strane (npr. PHP) koje koriste neki izvor podataka (npr. podatke iz MySQL baze) nazivaju se dinamike veb strane. One se zasnivaju na principu da se HTML kod ne stvara sve dok korisnik ne poeli da vidi veb stranicu. To dinamiko stvaranje stranica omoguuje da one budu prilagoene korisnikovim zahtevima, da zavise od prethodnih akcija korisnika, od vremena i mesta kad je pristupio lokaciji, od njegovog identiteta i specifinih potreba.

1. Pretraiva alje HTTP zahtev koji sadri URL

Korisnik 6. Web server stranu alje do pretraivaa 2. Web server aktivira aplikacioni server

5. HTML strana sa traeniminformacijama Web server 4. Povratna informacija

Aplikacioni server 3. Aplikacioni server alje zahteve i instrukcije do database servera

Database server

Slika 2: Pristup dinamikim veb stranama

Pristup dinamikim veb stranicama tee po sledeem redosledu: 1. Veb ita alje HTTP zahtev veb serveru. HTTP zahtev sadri URL sa traenom stranicom. 2. Veb server prihvata klijentski zahtev i aktivira aplikativni server. Aplikativni server je softver koji moe i ne mora biti instaliran na istom raunaru kao i veb server. 3. Na osnovu informacija primljenih u klijentskom zahtevu, aplikativni server prosleuje upit ka serveru baze podataka. 4. Na osnovu dobijenog zahteva, na serveru baze podataka izvrava se odgovarajui upit. Rezultat obrade alje se nazad do aplikativnog servera 5. Aplikativni server formira HTML stranicu u koju ugrauje informacije dobijene iz baze podataka. HTML stranica prosleuje se veb serveru. 6. Veb server alje HTML stranicu do klijentskog raunara. 4

1 PHP i rad sa bazama podataka


PHP podrava API-je za pristup svim poznatim bazama podataka. Programski jezik PHP se u praksi najee koristi sa MySQL bazom podataka. MySQL je efikasan server za upravljanje bazama podataka. Predstavlja opensource reenje sa odlinim performansama. Programski jezik PHP je modularan, to znai da se sastoji iz jezgra (core) i ekstenzija, koje se po potrebi mogu ukljuiti. Pristup bazi podataka u programskom jeziku PHP ostvaruje se pomou odgovarajuih PHP ekstenzija, koje su najee podrazumevano ukljuene. Bazi je mogue pristupiti na vie naina. Poto se najvie koristi MySQL server, u daljem tekstu bie razmatran pristup ovoj bazi. MySQL bazi je mogue pristupiti korienjem ekstenzije php_mysql, php_mysqli ili php_pdo_mysql. Takoe, PHP ima podrku za povezivanje na bilo koji sistem za upravljanje podacima pomou ODBC drajvera. Navedene ekstenzije je mogue ukljuiti ili iskljuiti konfigurisanjem php.ini fajla ili izborom opcije PHP PHP extensions kod WAMP servera (slika 2).

Slika 3: PHP ekstenzije kod WAMP servera

Pre pojave verzije 5 PHP-a, MySql bazi moglo se jedino pristupiti korienjem odgovarajuih funkcija ugraenih u php_mysql ekstenziju. Ovaj pristup se i dalje koristi, ali je danas ve prevazien, zato to se bazi pristupalo korienjem proceduralnih naredbi (nije postojala objektno-orijentisana podrka), nije bilo podrke za jednostavnu promenu kodnog rasporeda baze (bez eksplicitnog poziva odgovarajuih SQL naredbi nije bio mogu korektan prikaz srpskih ili bilo kojih drugih UTF-8 karaktera), nije bilo podrke za pripremljene SQL naredbe (prepared statements) i transakcije nisu bile podrane. Pojavom verzije 5 programskog jezika PHP, dodate su dve nove ekstenzije za pristup MySQL bazi. To su php_mysqli (MySql Improved) i php_pdo (PHP DATA OBJECTS). Obe ekstenzije podravaju objektno-orijentisan pristup bazi. Dok ekstenzija php_mysqli slui iskljuivo za pristup MySql bazi podataka, php_pdo predstavlja univerzalnu ekstenziju za pristup bilo kom podranom serveru baze podataka (preduslov je da postoji odgovarajui drajver za datu bazu). U tabeli 1 nalazi se uporedni prikaz navedene tri ekstenzije: Verzija PHP-a u kojoj se prvi put pojavljuje Ukljuena u PHP verziji 5.x Jo uvek se razvija Preporuena ekstenzija od strane MySQL-a Podrava razliite kodne rasporede Podrava pripremljene upite na serverskoj strani Podrava pripremljene upite na klijentskoj strani Podrava skladitenje procedura Podrava izvravanje vie upita odjednom Podrava sve MySQL 4.1+ funkcionalnosti php_mysql 3.0 da ne ne ne ne ne ne ne ne php_mysqli 5.0 da da da (najbolja opcija) da da ne da da da php_pdo_mysql 5.0 da da da da da da da Uglavnom da Uglavnom da

Tabela 1: Uporedni prikaz PHP ekstenzija za rad sa MySQL bazom

Postoji etiri osnovne operacije nad bazom podataka, odnosno nad perzistentnim skladitem podataka. To su operacija kreiranja podataka (create), operacija itanja podataka (read), operacija auriranja podataka (update) i operacija brisanja podataka (delete). U poslovnim aplikacijama, uvek se koriste sve navedene operacije. U literaturi su one esto oznaene nazivom crud (create, update, update, delete).

1.1 PhpMyAdmin
Kao alat za jednostavno upravljanje MySQL bazom podataka, esto se koristi aplikacija PhpMyAdmin. U pitanju je opensource veb aplikacija napisana u programskom jeziku PHP, koja omoguava kreiranje novih baza podataka, izmenu postojeih baza, rad sa tabelama, pregled, unos, izmenu i brisanje podataka, kao i izvravanje SQL upita. WAMP server, kao i veina kombinovanih Apache PHP MySQL reenja, ukljuuju PhpMyAdmin aplikaciju. Ukoliko se koristi WAMP server, ovoj aplikaciji se pristupa pomou adrese http://localhost/phpmyadmin/ ili jednostavnim klikom na ikonicu WAMP-a i izborom opcije PhpMyAdmin.

Na slici 3 prikazan je interfejs aplikacije PhpMyAdmin. Sa leve strane nalazi se spisak postojeih baza podataka. Na poetnoj strani je mogue kreirati novu bazu korienjem opcije Create New Database. Isto je mogue uraditi izborom opcije Databases. Korienjem opcije Privileges mogue je kreirati korisnike MySQL baze, kojima je mogue dodeliti privilegije izvravanja odreenih operacija nad bazama.

Slika 4: PhpMyAdmin

1.1.1 Kreiranje nove baze


Izborom opcije Databases mogue je kreirati novu bazu podataka. Na slici 4 prikazana je forma za dodavanje nove baze.

Slika 5: Kreiranje nove baze

Izborom odgovarajue opcije u padajuoj listi potrebno je izabrati kodni raspored baze. Za pravilan prikaz svih karaktera (pa i srpskih slova), trebalo bi izabrati opciju utf8_unicode_ci. U polje za unos teksta trebalo bi uneti eljeni naziv baze podataka. Primer 1: Kreiranje nove baze podataka (PhpMyAdmin) Za kreiranje nove baze podataka sa nazivom bazanovosti, u ovo polje treba uneti bazanovosti. Ova baza e biti koriena i u svim narednim primerima u skripti. Nakon kreiranja nove baze, pojavie se ekran prikazan na slici 5. 7

Slika 6: Kreiranje tabele

Nakon kreiranja baze, pojavie se poruka No tables found in database. To znai da je kreirana baza prazna i da je potrebno kreirati tabele. U polje Name potrebno je uneti naziv tabele, a u polje Number of Fields broj kolona (polja) koje e se nalaziti u novokreiranoj tabeli. Zatim je potrebno definisati kolone (slika 6).

Slika 7: Definisanje kolona

Pojavie se polja za definiciju svake kolone ponaosob. Broj ovih polja zavisi od izabranog broja kolona u prethodnom koraku. Za svaku kolonu potrebno je definisati sledee parametre: Field naziv kolone. Type tip vrednosti kolone. Tipovi podataka koji se najee koriste su: INT celobrojna vrednost DOUBLE decimalna vrednost. Obavezan je i parametar LENGTH, koji se unosi u formatu a,b. Parametar a predstavlja ukupan broj cifara broja, a parametar b predstavlja broj cifara iza decimalnog zareza. Na primer, ukoliko se u polje LENGTH unese 8,2; to znai da se moe skladititi najvie estocifren broj, sa dva decimalna mesta. Ukoliko se unese na primer broj 123456.7890, ovaj broj e biti zaokruen na najbliu vrednost (123456.79). VARCHAR krai tekst. Pogodan je za naslove, e-mail adrese, imena i dr. Potrebno je definisati i parametar LENGTH (maksimalno 255 karaktera). TEXT dui tekst. Pogodan je za sadraj nekog lanka, vest i sl. 8

DATETIME polje za uvanje vremena i datuma. Ovo polje prihvata vrednosti unete u formatu YYYY-MM-DD HH:MM. Length/Values maksimalna duina polja ili skup moguih vrednosti. Default podrazumevana vrednost polja, ukoliko se ne definie pri novom unosu. Collation kodni raspored. Ukoliko se ne izabere, primenjuje se kodni raspored baze. Attributes atributi. Moe biti binarna vrednost ili vrednost bez znaka. Obino se ostavlja nepopunjeno. Null selektuje se ukoliko je mogue da vrednost polja bude NULL. Index bira se ukoliko polje ujedno predstavlja klju. PRIMARY se odnosi na primarni klju, UNIQUE na jedinstveni klju, opcija INDEX se bira ukoliko se eli indeksiranje baze po tom polju, a FULLTEXT je opcija za puno indeksiranje. AUTO_INCREMENT ova opcija se bira ukoliko je izabrano da vrednost polja Index bude PRIMARY. Odnosi se na automatsku dodelu primarnog kljua, po principu automatske inkrementacije. Comments ovde se unose opcioni komentari vezani za dato polje.

Opcija Storage Engine odnosi se na nain skladitenja podataka u datoj tabeli MySQL baze. MySQL podrava dva osnovna tipa skladitenja InnoDB i MyISAM. Njihov uporedni prikaz dat je u tabeli 2: Spoljni kljuevi Integritet podataka Zakljuavanje podataka Indeksiranje (pun tekst) Oporavak podataka Brzina upisivanje podataka (INSERT, UPDATE) Brzina itanja podataka (SELECT) Hardverska zahtevnost i potronja sistemskih resursa Rad sa transakcijama InnoDB podrava da na nivou reda ne bolja podrka bri sporiji zahtevniji da MyISAM ne podrava ne na nivou tabele da loija podrka sporiji bri manje zahtevan ne

Tabela 2: Uporedni prikaz InnoDB i MyISAM naina skladitenja

Primer 2: Kreiranje tabele (PhpMyAdmin) Baza bazanovosti treba da sadri jednu tabelu, definisanu relacionim modelom: novosti (idnovost, naslov, tekst) Za kreiranje ove tabele, nakon kreirane baze iz primera 1, treba uneti novosti u polje Create new table on database bazanovosti -> Name, a u polje Number of Fields treba uneti 3, zatim treba kliknuti na dugme Go. Nakon kreiranja tabele, treba definisati polja kao na slici 6 i kliknuti na taster GO.

Novokreiranu tabelu novosti mogue je napuniti podacima korienjem opcije Insert, a zatim unosom podataka (slika 7).

Slika 8: Ubacivanje novih podataka

Svaka grupa polja (idnovost, naslov, tekst) predstavlja jedan red podataka u tabeli. Tabelu je mogue napuniti proizvoljnim podacima na ovaj nain. Izborom opcije Browse (slika 8), mogue je videti sadraj tabele, odnosno sve podatke koji su uneti.

Slika 9: Pregled sadraja tabele

10

1.1.1 Korienje SQL naredbi za kreiranje baze


PhpMyAdmin podrava i kreiranje baze korienjem SQL naredbi. Potrebno je vratiti se na poetnu stranu PhpMyAdmin-a, a zatim kliknuti na opciju SQL (slika 9). Pojavie se forma za unos SQL naredbi. Opcija Delimiter odnosi se na znak koji razdvaja linije u upitu. Podrazumevano se koristi taka-zarez (;).

Slika 10: Korienje SQL naredbi

Primer 3: Kreiranje nove baze podataka (SQL) Baza bazanovosti moe da se kreira i pomou SQL naredbi. Rezultat je potpuno isti kao i u primeru 2. SQL naredbe za kreiranje ove baze sa tabelom i podacima su: CREATE DATABASE bazanovosti CHARSET=utf8 COLLATE=utf8_unicode_ci ; USE bazanovosti; CREATE TABLE novosti ( idnovost INT( 20 ) NOT NULL AUTO_INCREMENT , naslov VARCHAR( 20 ) NOT NULL , tekst VARCHAR( 45) NOT NULL , PRIMARY KEY ( idnovost ) ); INSERT INTO novosti (idnovost, naslov, tekst) VALUES (1, 'Neki naslov', 'Neki tekst');

1.1.2 Izvoz podataka


Da bi se sauvala baza podataka sa svim pripadajuim tabelama i podacima, potrebno je vratiti se na poetnu stranu PhpMyAdmin aplikacije, a zatim izabrati opciju Export (slika 10). Sa leve strane, ispod opcije Export, nalazi se lista dostupnih baza podataka. Potrebno je selektovati eljenu bazu za izvoz. Ispod liste baza, potrebno je izabrati opciju SQL kao format izvoza (uglavnom je podrazumevano izabrana). Pri dnu strane nalazi se opcija Save as file. Ukoliko je izabrana, baza e se eksportovati u obliku fajla koji e biti preuzet (download-ovan) na raunar. Ako ova opcija nije izabrana, prikazae se lista SQL naredbi koje slue za kreiranje ove baze. U polje File Name Template mogue je uneti eljeni naziv 11

fajla koji e se sauvati na raunaru, kao rezultat izvoza baze. Nakon izvrenih podeavanja, treba kliknuti na taster GO, ime e se sauvati baza na lokalnom raunaru, u folderu za Download fajlova (ili na eljenoj lokaciji, ako je browser tako konfigurisan).

Slika 11: Izvoz baze

1.1.3 Uvoz podataka


Da bi se prethodno izvezeni podaci uvezli, neophodno je otii na poetnu stranu PhpMyAdmin-a i izabrati opciju Import (slika 11). Ovde treba izabrati SQL fajl sa raunara (Choose File) i kliknuti na taster GO.

Slika 12: Uvoz baze

12

1.2 PHP, MySQL i korienje naih slova


Ukoliko se ne izvri pravilno podeavanje razvojnog okruenja i baze podataka, mogue je da se naa irilina ili latinina slova na stranici nee pravilno prikazati. Sve PHP fajlove je potrebno snimati u UTF-8 kodnom rasporedu. Podeavanja naravno variraju u zavisnosti od razvojnog okruenja koje se koristi. Kod podeavanja Notepad++ okruenja, trebalo bi promeniti podrazumevano podeavanje kodnog rasporeda izborom podeavanja Settings Preferences New Document / Default Directory, a zatim opcije UTF-8 without BOM u grupi opcija Encoding. BOM predstavlja skraenicu od Byte Order Mark. To je unicode karakter koji definie poredak bajtova dokumenta (da li je u pitanju big-endian ili littleendian). Ovaj karakter se dodaje na sam poetak dokumenta, i moe da predstavlja problem u radu sa PHP sesijama, upravo zbog slanja HTTP header-a koji mora uvek da bude na poetku HTTP zahteva. Zbog toga je poeljno da se BOM ne koristi. Prilikom otvaranja PHP dokumenta u razvojnom okruenju Notepad ++, uvek je mogue videti kodni raspored u kome je dokument sauvan pomou opcije Encoding (slika 12).

Slika 13: Encoding podeavanja u programu Notepad ++

Ukoliko je izabrana opcija Encode in UTF-8 without BOM, to znai da su podeavanja kodnog rasporeda korektna. Ukoliko je izabrana neka druga opcija, postoji mogunost konvertovanja dokumenta u unicode izborom opcije Convert to UTF-8 without BOM, nakon ega je potrebno ponovo sauvati dokument. Kod HTML stranica, veoma je poeljno dodavanje meta taga koji opisuje kodni raspored. U pitanju je meta tag:
<meta http-equiv="content-type" content="text/html; charset=utf-8" />

HTML dokument bi dakle ovako trebalo da izgleda:


<!DOCTYPE html> <html> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8" /> <title>Moja strana</title> </head> <body> <p>Neki sadraj strane</p>

13

</body> </html>

Prilikom kreiranja MySQL baze, uvek treba voditi rauna o parametrima collation i charset. To je detaljnije objanjeno u prethodnom poglavlju. Trebalo bi koristiti utf8_unicode_ci raspored. Konano, bitno je da se utf8 kodni raspored koristi i prilikom pozivanja baze iz PHP-a. Vie o tome bie objanjeno u narednim poglavljima.

1.3 Pregled najee korienih SQL upita


SQL predstavlja struktuirani jezik za upite. Osnovna sintaksa SQL upita je praktino ista kod svih dostupnih servera bazi podataka, uz neke manje specifinosti. U sledeoj tabeli dat je kratak prikaz SQL upita (SQL query) o kojima e kasnije biti rei: Sintaksa upita CREATE DATABASE ime_baze CREATE TABLE ime_tabele ( Ime_kolone1 tip podataka (velicina), Ime_kolone2 tip podataka (velicina), Ime_kolone3 tip podataka (velicina) . ) INSERT INTO ime_tabele (ime_kolone1, ime_kolone2, ime_kolone3) VALUES (vrednost_za_kolonu1, vrednost_za kolonu2, vrednost_za_kolonu3) SELECT ime_kolone1,ime_kolone2, ime_kolone3, ime_koloneN FROM ime_tabele. (umesto naziva kolona moe se staviti * , to je dkorer znak da je sve selektovano). SELECT ime_kolone1,ime_kolone2, ime_kolone3, ime_koloneN FROM ime_tabele WHERE ime_kolone=vrednost SELECT ime_kolone1,ime_kolone2, ime_kolone3, ime_koloneN FROM ime_tabele ORDER BY ime_kolone (desc). SELECT ime_tabele1.ime_kolone1, ime_tabele1.ime_kolone2, ime_tabele1.ime_kolonen, ime_tabele2.ime_kolone1, ime_tabele2.ime_kolone2, ime_tabele2.ime_kolonen FROM ime_tabele1 JOIN ime_tabele2 ON Funkcija Kreira novu SQL bazu Kreira tabelu u okviru selektovane baze podataka. Navode se imena svih kolona i tipovi podataka koje e podravati ove kolone. Za tipove podataka u MySQL u, pogledati reference za MySQL. Ubacuje konkretne vrednosti u kreiranu tabelu u MySQL bazi podataka. Selektuje odabrane, ili sve kolone iz tabele

Selektuje odabrane kolone na osnovu zadatog kriterijuma. Selektuje odabrane kolone iz tabele i razvrstava ih u opadajuem ili rastuem redosledu na osnovu neke kolone. Ako se ne navede Desc, po default u se podrazumeva rastui redosled. Selektuje izabrana polja iz dve tabele, koje su spojene izjednaavanjem spoljnog i primarnog kljua.

14

ime_tabele1.kljuc1 = ime_tabele2.kljuc2 UPDATE ime_tabele SET ime_kolone=nova_vrednost WHERE ime_kolone=stara_vrednost DELETE FROM ime_tabele WHERE ime_kolone=neka_vrednost

Menja konkretne vrednosti iz odreene tabele na osnovu zadatih kriterijuma. Brie konkretne vrednosti iz odreene tabele na osnovu zadatih kriterijuma.

Tabela 3: Najei SQL upiti

15

2 Ekstenzija php_mysql
Ova ekstenzija postoji od verzije 3 programskog jezika PHP. Nalazi se i u aktuelnoj verziji 5, radi odranja kompatibilnosti sa starijim PHP aplikacijama, meutim vie se ne odrava. Prilikom kreiranja nove PHP aplikacije, ne preporuuje se korienje ove ekstenzije.

2.1 Konekcija na MySql server


Da bi se moglo upravljati podacima iz baze, neophodno je uspostaviti konekciju sa serverom na kojem se ta baza nalazi. Serveri se nalaze na mrei i njima se pristupa pomou IP-a ili domene (hosta). Uz podatak o hostu servera, potrebni su korisniko ime i lozinka da bi se uspeno povezalo na server i komuniciralo sa njim. U PHP postoji ugraena funkcija za povezivanje sa serverom mysql_connect. Funkcija vraa broj koji je referenca ka uspostavljenoj konekciji, ili false ukoliko konekcija nije uspela. Konekcija ostaje otvrena sve dok se ne pozove funkcija mysql_close ili dok se ne izvri PHP skript. U sledeoj tabeli su date neke od osnovnih funkcija za spajanje na MySQL server. Naziv funkcije mysql_connect Sintaksa Opis mysql_connect(ime servera:port, Povezuje PHP skriptu sa korisniko ime, ifra ukoliko MySQL bazom. Ako je postoji). baza zatiena ifrom, ifra se mora uneti kao parameter. mysql_close (naziv promenljive Zatvara PHP konekciju kojoj je dodeljna vrednost sa bazom. mysql_connect funkcije) mysql_query( upit koji se izvrava U okviru ove naredbe se nad MySQL bazom, naziv moe koristiti bilo koji promenljive kojoj je dodeljena upit: za kreiranje tabele, vrednost mysql_connection()) za kreiranje baze, za popunjavanje baze, auriranje baze, itanje iz baze... mysql_error() Izvetava o mysql greci mysql_select_db(ime_baze) Bira MySQL bazu nad kojom e vriti upite
Tabela 4: MySQL funkcije

mysql_close mysql_query

mysql_error mysql_select_db

Dobra praksa je da se prilikom dizajniranja PHP veb aplikacije koja koristi bazu podataka napravi jedan fajl u kome je definisano spajanje na MySQL server i odabir baze. Ovo je dobra praksa, zato to postoji mogunost promene hosting provajdera i u tom sluaju dolazi do promene parametara baze podataka. Ukoliko se parametri uvaju samo u jednom fajlu koji se ukljuuje pomou PHP funkcije include ili require u ostale fajlove gde je potreban pristup bazi, prilikom eventualne naknadne promene parametara za pristup bazi neophodna je intervencija samo na jednom mestu. U sluaju da se spajanje na MySQL server navodi u svim fajlovima koji koriste podatke iz baze, neophodna je intervencija na vie mesta, to nije praktino, jer moe da se dogodi da veb programer previdi neku stranicu i da ta stranica nee moi da se uspeno povee na server baze podataka. 16

Primer 4: Povezivanje sa bazom podataka (php_mysql) Pomou fajla konekcija.php se vri povezivanje sa serverom na kojem je smetena baza. <?php $mysql_server = "localhost"; $mysql_user = "root"; $mysql_password = ""; $mysql_db = "bazanovosti"; if (!$db=mysql_connect($mysql_server, $mysql_user, $mysql_password)) { die ("<p>Spajanje na mysql server je bilo neuspeno</p>"); } if (!mysql_select_db($mysql_db, $db)) { die ("<p>Greka pri odabiru baze</p>"); } else { mysql_query("SET NAMES utf8"); mysql_query("SET CHARACTER SET utf8"); mysql_query("SET COLLATION_CONNECTION='utf8_unicode_ci'"); } ?>

Ukoliko su MySql funkcijama dati tane podaci rezultat skripte bi trebalo da bude prazna stranica. Samo spajanje sa serverom se obavlja pomou mysql_connect funkcije. Funkciji se prosleuju tri argumenta. Prvi je host na kom se nalazi server. Ovde se moe uneti IP ili hostname servera, ali skoro uvek se radi o alliasu localhost na IP 127.0.0.1 (barem kod veine komercijalnih hosting providera). Drugi argument je korisniko ime pomou koje se spaja, a trei lozinka za tog korisnika. Ukoliko su svi dati podaci tani, pa je mysql pristupaan i operacionalan funkcija e vratiti spoj sa serverom. Ako je neka od informacija netana ili se neto desilo sa samim MySql serverom funkcija vraa false. Jo jedna vrlo bitna stvar je proveravati uspeh operacije spajanja. Naime, skoro uvek itava poslovna logika aplikacije zahteva uspenu konekciju na server. Sledei korak pri spajanju sa MySql serverom je odabir baze. Mysql_select_db funkcija kao prvi argument dobija ime baze koja se koristi, a kao drugi vezu tj spoj na MySql server gde se ta baza nalazi. Poto je spoj (rezultat mysql_connect funkcije) ubaen u varijablu $db ona je prosleena na drugo mesto. Ovo nije obavezni argument, tj. mogao je biti izostavljen pa mysql_select_db funkciju pozvati u mysql_select_db("baza") obliku i sve bi i dalje radilo. Radi se o tome da PHP automatski pamti poslednju otvorenu vezu na MySql server pa je uvek po defaultu koristi u svim mysql funkcijama gdje je taj argument izostavljen (recimo u funkciji koja izvrava neki SQL upit na serveru). No, ukoliko se u skripti spaja na dva razliita servera, ili ostvaruju dve zasebne veze na isti server i ne koristi taj argument u MySql funkcijama PHP e uvek koristiti onu vezu koja je poslednja otvorena. Tako da se u toj

17

situaciiji mora prosleivati ona varijabla koja u sebi sadri onaj spoj na kom treba izvriti neka operaciju.

2.2 Ubacivanje podataka u bazu (naredba INSERT INTO)


Baza i njoj pripadajue tabele su u poetku prazne nemaju podataka. Osnovna operacija za unos podataka je INSERT INTO. Podaci se preko komandnog panela ubacuju izborom opcije INSERT. Upit kojim se ubacuju podaci u tabelu novosti :
INSERT INTO `novosti` ( `idnovost` , `naslov` , `tekst` ) VALUES ( '', 'Naslov1', 'Ovo je prva vest' ), ( '', 'Naslov2', 'Ovo je druga vest' )

Kod naziva tabele je vrlo bitno napisati njeno ime u pravilom caseu jer su imena baza, tabela i polja case sensitive. Kao to se vidi, u zagradama su navedena polja tabele, ali jedno nedostaje. Polje idnovost nije navedeno i ne radi se o greci u pisanju. Naime, ukoliko se neko polje izostavi u listi njemu se automatski upisuje defaultna vrednost (koja se moe postaviti pri stvaranju tabele). U ovom sluaju je pri stvaranju tabele polju idnovost data auto_increment osobina koja pri svakom insertu tom polju pridruuje po defaultu vrednost veu za 1 od poslednje upisane. Nakon liste polja dolazi VALUES ime se naznaava da sledi lista vrednosti koja se ubacuje u tablicu. Vrednost koja se ubacuje u jedno od polja mora biti na istoj poziciji u listi vrednosti kao i ime polja u koje e se sauvati u listi polja. Kod stvaranja liste polja nije bitan redosled. Bitno je jedino da se ime polja u svojoj listi pozicijom poklapa sa vrednosti u listi vrednosti Jedna od osnovnih funkcionalnosti PHP skriptova je ubacivanje podataka u bazu. Najee se podaci prikupljaju od korisnika. U tekstu sledi primer ubacivanja podataka prikupljenih preko forme. Primer 5: Unos podataka u bazu preko forme (php_mysql) <!DOCTYPE html> <html> <head> <title>Unos novosti</title> <meta http-equiv="Content-Type" content="text/html; 8" /> </head> <body> <h1>Unos novosti</h1> <hr/> <form method="post" action=""> Naslov : <input type="text" name="naslov" /><br/> Tekst : <textarea name="tekst"></textarea><br/> <input type="submit" name="unos" value="Ubaci" /> </form> <?php

charset=utf-

18

if (isset($_POST["unos"])){ //Prikupljanje podataka sa forme if (isset($_POST['naslov'])&&isset($_POST['tekst'])){ $naslov = $_POST['naslov']; $tekst = $_POST['tekst']; //Operacije nad bazom include "konekcija.php"; $sql="INSERT INTO novosti (naslov, tekst) VALUES ('".$naslov."', '". $tekst."')"; if (mysql_query($sql)) { echo "<p>Novost je uspeno ubaena</p>"; } else { echo "<p>Nastala je greka pri ubacivanju novosti</p>" . mysql_error(); } } else { //Ako POST parametri nisu prosleeni echo "Nisu prosleeni parametri!"; } mysql_close($db); } ?> </body> </html>

Struktura, tj. logika ove skripte sledi logiku same operacije. Prvi korak je unos podataka u formu, a drugi je ubacivanje tih podataka u bazu. Kao uslov obavljanja prvog ili drugog koraka je postojanje vrednosti u varijabli $_POST["unos"], tj. varijable koju stvara pritisnuti submit taster forme imena unos. U form tagu action atribut nema vrednost. Kada je action atribut definisan na ovaj nain podaci se alju ka stranici na kojoj se nalazi forma. Forma se prikazuje na unosvesti.php pa e se i nakon submit - ovanja forme opet otvarati ista stranica. Drugi korak ubacuje podatke iz forme u bazu. Da bi se moglo neto ubaciti u bazu prvo se mora spojiti na MySql server i odabrati je, to je uraeno u prvom primeru koji je ubaen u dbsproj.php pa je ovde samo ukljuujen.
include "konekcija.php";

Nakon uspenog spajanja na bazu generie se SQL upit:


$sql="INSERT INTO novosti (naslov, tekst) VALUES ('$_POST[naslov]', '$_POST[tekst]')";

Sledei korak je stvaranje stringa u kojem se nalazi sam SQL upit za unos podataka u tablicu.
if (mysql_query($sql))

19

{ echo "Novost je uspesno ubaena"; } else { echo "Nastala je greka pri ubacivanju novosti<br>" . mysql_error(); }

Ovo je glavni deo skripte koji obavlja samu komunikaciju sa MySQL serverom, tj. izvrava SQL upit na njemu. Obavlja se pomou mysql_query() funkcije. mysql_query() funkcija prima dva argumenta. Prvi je string podatak koji sadri valjani upit (SQL ili neku MySQL naredbu) koji je obavezan, dok je drugi neobavezan, a radi se o otvorenom i validnom spoju na MySQL server koji je u dbsproj.php skripti ubaen u $db varijablu. U sluaju INSERT upita mysql_query() vraa true ukoliko je upit uspeno obavljen ili false u suprotom. Iz tog razloga je mogue pomou if-a proveriti da li je novost ubaena u bazu i u zavisnosti od toga ispusati odgovarajuu poruku korisniku.

2.3 itanje podataka iz baze (naredba SELECT)


Najjednostavniji primer je upit koji pribavlja sve redove iz jedne tabele.
SELECT * FROM novosti

Upit poinje nazivom vrste upita. Ovo je pravilo koje dele svi upiti za manipulaciju podacima u osnovnim oblicima. Nakon imena operacije sledi lista polja koja e se pojaviti u tablici rezultata upita. Zvezdica je skraenica koja govori da e se pribaviti sva polja iz navedenih tabela. Nakon liste polja sledi FROM koji govori da sledi lista tabela iz kojih se podaci pribavljaju. Ovo su ujedno i svi obavezni delovi jednog valjanog SQL SELECT upita pa, ukoliko jedan od njih bude izostavljen MySql e javiti greku i nee obaviti upit. Rezultat upita nije sortiran ni po jednom polju, ali redovi su vraeni po redosledu upisa u bazu, po idnovost polju poto se radi o auto_increment polju koje svakom novom redu daje vrednost veu za 1 od onog prolog.
SELECT * FROM novosti ORDER BY idnovost DESC

Da bi rezultati upita bili sortirani dodata je ORDER BY klazula u ovom sluaju na njegov kraj. ORDER BY mora biti propraen imenima polja po kojima se eli sortirati rezultat pa nain sortiranja. U ovom sluaju se radi o polju idnovost DESC (descending) nainom, tj. u opadajuem redosledu. Suprtotno, tj. u rastuem redosledu, se moe sortirati tako da se izostavi DESC ili umesto njega upie ASC (ascending). Ukoliko se izostavi smer sortiranja rezultata podrazumevani smer je uzlazan. Primer 6: Pregled novosti (php_mysql) <!DOCTYPE html> <html> <head> <title>Pregled novosti</title>

20

<meta http-equiv="Content-Type" content="text/html; charset=utf8" /> </head> <body> <?php include "konekcija.php"; $sql="SELECT naslov, tekst FROM novosti ORDER BY idnovost DESC"; if (!$q=mysql_query($sql)) { echo "<p>Nastala je greska pri izvodenju upita</p>" . mysql_query(); die(); } if (mysql_num_rows($q)==0) { echo "Nema novosti"; } else { ?> <table> <tr> <td><b>Naslov</b></td> <td><b>Tekst</b></td> </tr> <?php while ($red=mysql_fetch_array($q)) { ?> <tr> <td><?php echo $red["naslov"]?></td> <td><?php echo $red["tekst"]?></td> </tr> <?php } ?> </table> <?php } mysql_close($db); ?> </body> </html>

SELECT upiti su najopirniji. Razlog tome je prilino oigledan, jer uz obavljanje upita moraju se podaci i pribaviti tj. u ovom sluaju ispisati u obliku tabele. Prva stvar koja se mora uraditi je kreiranje upita.
$sql="SELECT naslov, tekst FROM novosti ORDER BY idnovost DESC";

Nije obavezno upite upisivati u varijablu pa onda tu varijablu prosleivati mysql_query() funkciji. Moe se sam upit napisati pravo u mysql_query() funkciju. Npr. ovako:
mysql_query("SELECT naslov, tekst FROM novosti ORDER BY idnovost DESC")

21

if (!$q=mysql_query($sql)){ echo "<p>Nastala je greka pri izvodenju upita</p>" . mysql_query(); die(); }

Ovog puta je ubaen rezultat mysql_query funkcije u varijablu. Ovo je obavezno jedino kod izvravanja SELECT upita dok kod izvravanja ostalih to moe biti izostavljeno. U cilju izrade skripte koja nee ispisivati neke PHP / MySQL error-e mora se pre ispisa samog rezultata upita proveriti da li ima rezultata za prikaz, pa ukoliko nema preduzeti odgovarajue korake da se korisnik obavesti o tome pa mu po potrebi ponuditi opcije to moe uiniti u toj situaciji. Ta provera se obavlja pomou :
if (mysql_num_rows($q)==0){ echo "Nema novosti"; }

Funkcija koja obavlja samu proveru je mysql_num_rows() koja kao argument prima result identifier pa vraa integer broj koji je jednak ili vei od nule. Normalno, result identifier mora biti vei od nule, tj. ova funkcija e javiti error ukoliko je pri obavljanju upita nastala greka tj. mysql_query() je vratio false vrednost umesto result identifiera. Mora se voditi rauna da se ova funkcija ne poziva ukoliko skripta nije prola upit. To je u ovoj skripti osigurano die() funkcijom ukoliko je nastala greka pri izvravanju upita. Rezultati se ispisuju u tablici radi bolje preglednosti i razumljivosti, to je vrlo bitno kod izrade dinamikih siteova sa bazama podataka. Rezultati se naravno u zavisnosti od sluaja ne moraju prikazivati u tabeli, ve mogu i da se prikau u ureenoj ili neureenoj listi, div tagovima i dr.
<table> <tr> <td><b>Naslov</b></td> <td><b>Tekst</b></td> </tr>

Pre samog ispisa u HTML-u su ispisani prvi red tabele sa nazivima redova. Bitno je naglasiti da se ovaj red nalazi van while petlje, poto se prikazuje samo jednom. Nakon to su ispisani headeri tabele, vraa se u PHP mode i kree se sa ispisom podataka.
<?php while ($red=mysql_fetch_array($q)){ ?> <tr> <td><?php echo $red["naslov"]?></td> <td><?php echo $red ["tekst"]?></td> </tr> <?php } ?>

Mysql_fetch_array() vraa red, t.j. niz koji se sastojih od svih polja rezultata s tim da je svako polje indeksirano brojem i svojim imenom.

22

Mysql_fetch_row() takoe vraa niz, sa tom razlikom da u njemu postoje samo numeriki indeksi. Mysql_fetch_assoc() isto vraa niz, ali u njemu se nalaze samo tekstualno indeksirana polja. etvrta navedena funkcija, mysql_fethc_object() umesto niza vraa objekat stvoren od polja reda. Sve gore navedene funkcije imaju zajedniko to da e vratiti false na kraju ovog skupa rezultata. Ovo ini while petlju idealnim alatom za pribavljanje svih rezultata jer e se obaviti onoliko puta koliko ima rezultata u skupu. Jo jedna zajednika stvar svim pomenutim funkcijama je da kao svoj argument dobijaju result identifier koji vraa mysql_query() funkcija.
while ($red=mysql_fetch_array($q))

U bloku naredbi while petlje ispisuje se jedan red tabele pa u pojedinu kolonu tog reda ispisuje pribavljenje vrednosti poput <?php echo $red["naslov"]?> ime se ispisuje naslov novosti.

2.4 Brisanje podataka (naredba DELETE)


SQL naredba za brisanje podataka je :
DELETE FROM tabela

U prevodu gornja naredba znai Obrii sve iz tabele imena tabela, ali ovo je oigledno situacija koja e se retko dogaati u nekim realnim skriptama, ve se obino radi o brisanju jednog ili manje grupe podataka. Dalje se vidi kako bi izgledao upit koji obavlja brisanje jedne novosti na osnovu njenog ID-a.
DELETE FROM novosti WHERE idnovost=1

Gornji upit e obrisati samo onu novost koja ima idnovost jednak 1. WHERE slui za naznaavanje da nakon njega slede uslovi pomou kojih se ograniava skup podataka nad kojima e se obaviti neka operacija.
DELETE FROM novosti WHERE naslov = Naslov1

U prevodu, zadato je MySql-u da obrie sve naslove koji imaju vrednost naslov1. Unutar WHERE klazule je mogue kombinovati vie uslova koji ograniavaju skup podataka nad kojima se obavlja operacija kombinovanjem logikim operatorima. WHERE moe shvatiti kao if u PHP-u koji se obavlja nad svakim redom tabele. Takoe, pomou DELETE naredbe nije mogue obrisati pojedinu vrednost unutar nekog polja tabele. Nije mogue obrisati naslov novosti iji je idnovst jednak 1. Za to se koristi UPDATE naredba koja e biti objanjena u sledeem poglavlju. Brisanje se najee implementira u kombinaciji sa prikazom sadraja baze. Prethodni primer e biti proiren tako da pored svake novosti postoji dinamiki generisan link, koji e tu novost da izbrie. Dinamiki generisani linkovi funkcioniu tako to se pored naziva stranice na koju vodi link prosleuje i GET parametar, koji je razliit na osnovu stavke kojoj pripada.

23

Kada se vri linkovanje, ako link poinje upitnikom (?), to znai da e voditi na tekuu php stranicu, a da e njoj proslediti date GET parametre.

Primer 7: Brisanje novosti (php_mysql) <!DOCTYPE html> <html> <head> <title>Pregled novosti</title> <meta http-equiv="Content-Type" content="text/html; charset=utf8" /> </head> <body> <?php include "konekcija.php"; if (isset ($_GET['akcija']) && isset ($_GET['idnovost'])){ $akcija = $_GET['akcija']; $id = $_GET['idnovost']; switch ($akcija){ case "brisanje": $upit = "DELETE FROM novosti WHERE idnovost = ".$id; if (!$q=mysql_query($upit)){ echo "Nastala je greska pri izvodenju upita<br/>" . mysql_query(); die(); } else { echo "<p>Brisanje zapisa je uspeno!</p>"; } break; default: echo "<p>Nepostojea akcija!</p>"; break; } } $sql="SELECT idnovost, naslov, tekst FROM novosti"; if (!$q=mysql_query($sql)){ echo "Nastala je greska pri izvodenju upita<br>" . mysql_query(); die(); } if (mysql_num_rows($q)==0) { echo "Nema novosti"; } else { ?> <table> <tr> <td><b>Naslov</b></td> <td><b>Tekst</b></td> <td><b>Akcija</b></td> </tr> <?php while ($red=mysql_fetch_array($q)) 24

{ ?> <tr> <td><?php echo $red["naslov"]?></td> <td><?php echo $red["tekst"]?></td> <td><a href="?akcija=brisanje&idnovost=<?php echo $red["idnovost"]? >">Brisanje</a></td> </tr> <?php } ?> </table> <?php } mysql_close($db); ?> </body> </html>

Prethodnom primeru, gde je bio objanjen prikaz podataka iz baze, dodata je funkcionalnost brisanja. SQL upit za listanje podataka morao je biti malo izmenjen, poto e biti neophodno korienje atributa idnovost, za generisanje dinamikog linka za brisanje novosti. Ispod ukljuivanja fajla konekcija.php, proverava se da li je prosleen GET parametar akcija i idnovost. Ukoliko jesu prosleeni, radi jednostavnost, definiu se promenljive akcija i id na osnovu prosleenih GET parametara, pa se zatim proverava vrednost parametra akcija pomou switch-case bloka naredbi. Ovde je mogue koristiti i if..else, meutim switch-case je bolje reenje, zato to moe da postoji vie razliitih akcija. Ukoliko je vrednost GET parametra akcija brisanje, kree se sa brisanjem.
$upit = "DELETE FROM novosti WHERE idnovost = ".$id; if (!$q=mysql_query($upit)){ echo "Nastala je greska pri izvodenju upita<br/>" . mysql_query(); die(); } else { echo "<p>Brisanje zapisa je uspeno!</p>"; }

Izvravanje upita je vrlo slino kao kod INSERT upita. Dovoljno je obaviti upit pomou mysql_query() funkcije. ak nije obavezno ubaciti njen rezultat u neku varijablu poto ne postoji potreba za njenim korienjem kasnije u skripti. Oigledno, ukoliko mysql_query() vrati true moe se pretpostaviti da je novost obrisana a ukoliko vrati false znai da je nastala neka greka koju e mysql_error() opisati. Da bi proverili da li je novost stvarno obrisana, moe se koristiti jo jedna mysql funkcija koja se nalazi u PHP-u. Radi se o mysql_affected_rows() funkciji. Funkcija vraa broj redova koji su bili zahvaeni poslednjom operacijom. Moe se koristiti samo nakon DELETE, UPDATE i INSERT upita, tj. upita koji vre izmene nad podacima tabela.
$sql="DELETE FROM novosti WHERE idnovost=" . $_GET["idnovost"]; if (mysql_query($sql)) { if (mysql_affected_rows() > 0 )

25

{ echo "Novost je uspeno obrisana"; } else { echo "Nije obrisana ni jedna novost!"; } } else { echo "Nastala je greka pri brisanju novosti<br>" . mysql_error(); }

Deo koda:
<td><a href="?akcija=brisanje&idnovost=<?php echo $red["idnovost"]? >">Brisanje</a></td>

se ispisuje u svakom prolazu petlje kroz red u tabeli. Odabirom opcije Brisanje ide se na link upisan u href atributu. U ovom sluaju to je isti onaj fajl koji se izvrava. Dodatni parameter je idnovost, koji dobija vrednost u zavisnosti od toga koji red je izabran.

2.5 Izmena postojeih podataka (naredba UPDATE)


Za izmenu podataka se koristi UPDATE naredba.
UPDATE novosti SET naslov="Novi naslov"

Kao i svi ostali upiti do sada i ovaj poinje navoenjem imena operacije koja se izvodi. Ovog puta je odmah nakon naziva naredbe navedena tabela u kojoj se ele napraviti izmene. Nakon imena tabele slede SET koji govori da slede parovi imena polja tabele sa pridruenim novim vrednostima. Nakon izvravanja gornjeg primera bi u svim redovima tabele naslov bio promenjen u Novi naslov. Ukoliko je potrebno izmeniti vie polja istovremeno, to bi bilo uinjeno ovakvim upitom:
UPDATE novosti SET naslov="Novi naslov", tekst="abcdefghijk"

Znai, za izvoenje izmena vrednosti u vie polja potrebno je dva naziva polja sa pridruenim vrednostima odvojiti zarezom. Normalno, izmena vrednosti svim redovima neke tabele je vrlo retka pojava u realnim skriptama. Iz tog razloga je mogue pomou WHERE klazule ograniiti skup podataka nad kojima se vri izmena. U konkretnom primeru bi to izgledalo od prilike ovako :
UPDATE novosti idnovost=1 SET naslov="Novi naslov", tekst="abcdefghijk" WHERE

Ovim upitom je izmenjen naslov i tekst novosti koja ima ID jednak jedan. Naredni primer se takoe nadograuje na prethodni. Potrebno je definisati dve nove akcije u switch-case bloku naredbi. U pitanju je akcija izmena_forma, koja prikazuje formu za izmenu izabranog reda i koja se poziva pomou generisanog dinamikog linka i akcija izmena, koja vri konkretnu UPDATE operaciju nad bazom (poziva se klikom na taster submit na formi prikazanoj pomou akcije izmena_forma). Dinamiki link za izmenu se generie na istovetan nain kao i dinamiki link za brisanje, uveden u prethodnom primeru. Naravno, u okviru jednog PHP fajla mogue je kombinovati GET i POST parametre. Pomou GET parametra

26

e se uvek prosleivati vrednost akcije i vrednost parametra idnovost, a pomou POST parametara prosleivae se nove vrednosti nakon izmene. Primer 8: Izmena novosti (php_mysql) <!DOCTYPE html> <html> <head> <title>Pregled novosti</title> <meta http-equiv="Content-Type" content="text/html; charset=utf8" /> </head> <body> <?php include "konekcija.php"; if (isset ($_GET['akcija']) && isset ($_GET['idnovost'])){ $akcija = $_GET['akcija']; $id = $_GET['idnovost']; switch ($akcija){ case "brisanje": $upit = "DELETE FROM novosti WHERE idnovost = ".$id; if (!$q=mysql_query($upit)){ echo "Nastala je greska pri izvodenju upita<br/>" . mysql_query(); die(); } else { echo "<p>Brisanje zapisa je uspeno!</p>"; } break; case "izmena_forma": ?> <h1>Izmena novosti</h1> <hr/> <form method="post" action="?akcija=izmena&idnovost=<?php echo $_GET['idnovost'];?>"> Naslov : <input type="text" name="naslov" /><br/> Tekst : <textarea name="tekst"></textarea><br/> <input type="submit" name="unos" value="Ubaci" /> </form> <?php break; case "izmena": if (isset ($_POST['naslov']) && isset ($_POST['tekst'])){ $naslov = $_POST['naslov']; $tekst = $_POST['tekst']; $upit="UPDATE novosti SET naslov='". $naslov ."', tekst='" . $tekst . "' WHERE idnovost=". $id; if (mysql_query($upit)){ if (mysql_affected_rows() > 0 ){ echo "<p>Novost je uspeno izmenjena.</p>"; } else { echo "<p>Novost nije izmenjena.</p>"; } } else { 27

echo "<p>Nastala je greka pri izmeni novosti</p>" . mysql_error(); } } else { echo "<p>Nisu prosleeni parametri za izmenu"; } break; default: echo "<p>Nepostojea akcija!</p>"; break; } } $sql="SELECT idnovost, naslov, tekst FROM novosti"; if (!$q=mysql_query($sql)){ echo "Nastala je greska pri izvodenju upita<br>" . mysql_query(); die(); } if (mysql_num_rows($q)==0) { echo "Nema novosti"; } else { ?> <h1>Prikaz novosti</h1> <hr/> <table> <tr> <td><b>Naslov</b></td> <td><b>Tekst</b></td> <td><b>Akcija</b></td> </tr> <?php while ($red=mysql_fetch_array($q)) { ?> <tr> <td><?php echo $red["naslov"]?></td> <td><?php echo $red["tekst"]?></td> <td><a href="?akcija=izmena_forma&idnovost=<?php echo $red["idnovost"]?>">Izmena</a></td> <td><a href="?akcija=brisanje&idnovost=<?php echo $red["idnovost"]? >">Brisanje</a></td> </tr> <?php } ?> </table> <?php } mysql_close($db); ?> </body> </html>

28

Kao i u dosadanjim primerima, na samom poetku skripte je ukljuen konekcija.php. Dodata je nova akcija izmena_forma. Ova akcija takoe prosleuje id novosti preko GET parametra i ukoliko je pozvana, prikazuje formu za izmenu. Generisan je dinamiki link ka ovoj akciji, na slian nain kao dinamiki link za brisanje. Klikom na taster submit, poziva se akcija izmena i prosleuje se parametar idnovost, koji je takoe prikupljen pomou GET metode. Ova akcija proverava da li su prosleeni POST parametri sa novim vrednostima, prikupljeni iz forme. Ukoliko jesu, izvrava se upit koji vri izmenu u bazi: $upit="UPDATE novosti SET naslov='". $naslov ."', tekst='" . $tekst . "' WHERE idnovost=". $id; if (mysql_query($upit)){ if (mysql_affected_rows() > 0 ){ echo "<p>Novost je uspeno izmenjena.</p>"; } else { echo "<p>Novost nije izmenjena.</p>"; } } else { echo "<p>Nastala je greka pri izmeni novosti</p>" . mysql_error(); } U praksi se najee menja samo jedno polje, a retko kada sva polja. Navedeni primer ne prosleuje postojee vrednosti polja u formu za izmenu, ime se poveava mogunost sluajne izmene nekog polja, odnosno mogunost da se izbrie sadraj nekog polja. Uvek bi trebalo proslediti vrednost tekueg polja iz baze u formu za izmenu polja. Sledei primer pokazuje kako je to mogue uraditi: Primer 9: Izmena novosti poboljana verzija (php_mysql) <!DOCTYPE html> <html> <head> <title>Pregled novosti</title> <meta http-equiv="Content-Type" content="text/html; charset=utf8" /> </head> <body> <?php include "konekcija.php"; if (isset ($_GET['akcija']) && isset ($_GET['idnovost'])){ $akcija = $_GET['akcija']; $id = $_GET['idnovost']; switch ($akcija){ case "brisanje": $upit = "DELETE FROM novosti WHERE idnovost = ".$id; if (!$q=mysql_query($upit)){ echo "Nastala je greska pri izvodenju upita<br/>" . mysql_query(); die(); } else { echo "<p>Brisanje zapisa je uspeno!</p>"; 29

} break; case "izmena_forma": $upit="SELECT idnovost, naslov, tekst FROM novosti WHERE idnovost=". $id; if (!$q=mysql_query($upit)){ echo "<p>Nastala je greska pri izvodenju upita</p>" . mysql_query(); die(); } else { if (mysql_num_rows($q)!=1){ echo "<p>Nepostojea novost.</p>"; } else { $novost = mysql_fetch_array($q); $naslov = $novost ['naslov']; $tekst = $novost ['tekst']; ?> <h1>Izmena novosti</h1> <hr/> <form method="post" action="?akcija=izmena&idnovost=<?php echo $_GET['idnovost'];?>"> Naslov : <input type="text" name="naslov" value="<?php echo $naslov;?>"/><br/> Tekst : <textarea name="tekst"><?php echo $tekst;?></textarea><br/> <input type="submit" name="unos" value="Ubaci" /> </form> <?php } } break; case "izmena": if (isset ($_POST['naslov']) && isset ($_POST['tekst'])){ $naslov = $_POST['naslov']; $tekst = $_POST['tekst']; $upit="UPDATE novosti SET naslov='". $naslov ."', tekst='" . $tekst . "' WHERE idnovost=". $id; if (mysql_query($upit)){ if (mysql_affected_rows() > 0 ){ echo "<p>Novost je uspeno izmenjena.</p>"; } else { echo "<p>Novost nije izmenjena.</p>"; } } else { echo "<p>Nastala je greka pri izmeni novosti</p>" . mysql_error(); } } else { echo "<p>Nisu prosleeni parametri za izmenu"; } break; default: echo "<p>Nepostojea akcija!</p>"; break; } } 30

$sql="SELECT idnovost, naslov, tekst FROM novosti"; if (!$q=mysql_query($sql)){ echo "<p>Nastala je greska pri izvodenju upita</p>>" . mysql_query(); die(); } if (mysql_num_rows($q)==0) { echo "<p>Nema novosti.</p>"; } else { ?> <h1>Prikaz novosti</h1> <hr/> <table> <tr> <td><b>Naslov</b></td> <td><b>Tekst</b></td> <td><b>Akcija</b></td> </tr> <?php while ($red=mysql_fetch_array($q)) { ?> <tr> <td><?php echo $red["naslov"]?></td> <td><?php echo $red["tekst"]?></td> <td><a href="?akcija=izmena_forma&idnovost=<?php echo $red["idnovost"]?>">Izmena</a></td> <td><a href="?akcija=brisanje&idnovost=<?php echo $red["idnovost"]? >">Brisanje</a></td> </tr> <?php } ?> </table> <?php } mysql_close($db); ?> </body> </html>

Dakle, jedina izmena u odnosu na prethodni primer jeste ubacivanje i izvravanje SELECT upita u akciji izmena_forma. Proverava se da li postoji tano jedna vrednost novosti sa datim id-om i ukoliko postoji, prikazuju se podaci u bazi. Ovde nije neophodno korienje while petlje, poto je u pitanju samo jedna vrednost. Konano, ukoliko bi se primer ubacivanja novog zapisa ubacio u ovaj fajl, dobio bi se primer sa svim CRUD operacijama u jednom fajlu.

31

Za to je potrebno definisati novu akciju unos. Poto ova akciji nisu potrebni dodatni parametri, kao to je idnovost, potrebno ju je definisati van swich-case bloka (poto se on izvrava nakon provere GET parametara akcija i idnovost). U okviru akcije, mogu se definisati i forma i samo izvravanje INSERT operacije nad bazom. Dovoljno je iskopirati deo koda iz primera za ubacivanje zapisa. Naravno, potrebno je promeniti action atribut prilikom definisanje forme, tako da bude ?akcija=unos.

Primer 10: Sve CRUD operacije u jednom fajlu (php_mysql) <!DOCTYPE html> <html> <head> <title>Pregled novosti</title> <meta http-equiv="Content-Type" content="text/html; 8" /> </head> <body> <?php include "konekcija.php"; if (isset ($_GET['akcija'])){ if ($_GET['akcija'] == 'unos'){ ?> <h1>Unos novosti</h1> <hr/> <form method="post" action="?akcija=unos"> Naslov : <input type="text" name="naslov" /><br/> Tekst : <textarea name="tekst"></textarea><br/> <input type="submit" name="unos" value="Ubaci" /> </form> <?php if (isset($_POST["unos"])){ //Prikupljanje podataka sa forme if (isset($_POST['naslov'])&&isset($_POST['tekst'])){ $naslov = $_POST['naslov']; $tekst = $_POST['tekst']; //Operacije nad bazom include "konekcija.php"; $sql="INSERT INTO novosti (naslov, tekst) VALUES ('".$naslov."', '". $tekst."')"; if (mysql_query($sql)) { echo "<p>Novost je uspeno ubaena.</p>"; } else { echo "<p>Nastala je greka pri ubacivanju novosti</p>" . mysql_error(); } } else { //Ako POST parametri nisu prosleeni echo "Nisu prosleeni parametri!"; } 32

charset=utf-

} } } if (isset ($_GET['akcija']) && isset ($_GET['idnovost'])){ $akcija = $_GET['akcija']; $id = $_GET['idnovost']; switch ($akcija){ case "brisanje": $upit = "DELETE FROM novosti WHERE idnovost = ".$id; if (!$q=mysql_query($upit)){ echo "Nastala je greska pri izvodenju upita<br/>" . mysql_query(); die(); } else { echo "<p>Brisanje zapisa je uspeno!</p>"; } break; case "izmena_forma": $upit="SELECT idnovost, naslov, tekst FROM novosti WHERE idnovost=". $id; if (!$q=mysql_query($upit)){ echo "<p>Nastala je greska pri izvodenju upita</p>" . mysql_query(); die(); } else { if (mysql_num_rows($q)!=1){ echo "<p>Nepostojea novost.</p>"; } else { $novost = mysql_fetch_array($q); $naslov = $novost ['naslov']; $tekst = $novost ['tekst']; ?> <h1>Izmena novosti</h1> <hr/> <form method="post" action="?akcija=izmena&idnovost=<?php echo $_GET['idnovost'];?>"> Naslov : <input type="text" name="naslov" value="<?php echo $naslov;?>"/><br/> Tekst : <textarea name="tekst"><?php echo $tekst;?></textarea><br/> <input type="submit" name="unos" value="Ubaci" /> </form> <?php } } break; case "izmena": if (isset ($_POST['naslov']) && isset ($_POST['tekst'])){ $naslov = $_POST['naslov']; $tekst = $_POST['tekst']; $upit="UPDATE novosti SET naslov='". $naslov ."', tekst='" . $tekst . "' WHERE idnovost=". $id; if (mysql_query($upit)){ if (mysql_affected_rows() > 0 ){ echo "<p>Novost je uspeno izmenjena.</p>"; } else { 33

echo "<p>Novost nije izmenjena.</p>"; } } else { echo "<p>Nastala je greka pri izmeni novosti</p>" . mysql_error(); } } else { echo "<p>Nisu prosleeni parametri za izmenu"; } break; default: echo "<p>Nepostojea akcija!</p>"; break; } } $sql="SELECT idnovost, naslov, tekst FROM novosti"; if (!$q=mysql_query($sql)){ echo "<p>Nastala je greska pri izvodenju upita</p>>" . mysql_query(); die(); } if (mysql_num_rows($q)==0) { echo "<p>Nema novosti.</p>"; } else { ?> <h1>Prikaz novosti</h1> <hr/> <table> <tr> <td><b>Naslov</b></td> <td><b>Tekst</b></td> <td><b>Akcija</b></td> </tr> <?php while ($red=mysql_fetch_array($q)) { ?> <tr> <td><?php echo $red["naslov"]?></td> <td><?php echo $red["tekst"]?></td> <td><a href="?akcija=izmena_forma&idnovost=<?php echo $red["idnovost"]?>">Izmena</a></td> <td><a href="?akcija=brisanje&idnovost=<?php echo $red["idnovost"]? >">Brisanje</a></td> </tr> <?php } ?> </table> <?php } mysql_close($db); ?> 34

<p><a href="?akcija=unos">Unos novosti</a></p> </body> </html>

35

3 Ekstenzija php_mysqli
Ova ekstenzija postoji od verzije 5 programskog jezika PHP. Danas se preporuuje njeno korienje, zato to ima vie funkcionalnosti od php_mysql ekstenzije i neto bolje performanse. Takoe, podrava objektno-orijentisano programiranje.

3.1 Konekcija na MySql server


Da bi se moglo upravljati podacima iz baze, neophodno je uspostaviti konekciju sa serverom na kojem se ta baza nalazi. Serveri se nalaze na mrei i njima se pristupa pomou IP-a ili domene (hosta). Uz podatak o hostu servera, potrebni su korisniko ime i lozinka da bi se uspeno povezalo na server i komuniciralo sa njim. Ekstenzija php_mysqli se povezuje na MySQL server i vri odabir baze kreiranjem novog objekta klase mysqli. Parametri konstruktora su : IP adresa ili hostname MySQL servera MySQL korisniko ime MySQL lozinka MySQL baza koja se odabira

Sintaksa povezivanja na MySQL bazu korienjem mysqli ekstenzije je sledea: $mysqli = new mysqli($mysql_server, $mysql_user, $mysql_pass, $mysql_db); Nakon kreiranja mysqli objekta, treba proveriti da li je konekcija uspena. Atribut connect_errno() vraa ifru greke ukoliko je nastupila. Zatim bi trebalo odabrati charset u kome se nalaze podaci. To se radi korienjem naredbe set_charset("set_karaktera"). Na primer, za izbor UTF-8 charset-a, treba izvriti naredbu: $mysqli->set_charset("utf8"); Dobra praksa je da se prilikom dizajniranja PHP veb aplikacije koja koristi bazu podataka napravi jedan fajl u kome je definisano spajanje na MySQL server i odabir baze. Ovo je dobra praksa, zato to postoji mogunost promene hosting provajdera i u tom sluaju dolazi do promene parametara baze podataka. Ukoliko se parametri uvaju samo u jednom fajlu koji se ukljuuje pomou PHP funkcije include ili require u ostale fajlove gde je potreban pristup bazi, prilikom eventualne naknadne promene parametara za pristup bazi neophodna je intervencija samo na jednom mestu. U sluaju da se spajanje na MySQL server navodi u svim fajlovima koji koriste podatke iz baze, neophodna je intervencija na vie mesta, to nije praktino, jer moe da se dogodi da veb programer previdi neku stranicu i da ta stranica nee moi da se uspeno povee na server baze podataka.

Primer 11: Povezivanje sa bazom podataka (php_mysqli) Pomou fajla konekcija.php se vri povezivanje sa serverom na kojem je smetena baza.

36

<?php $mysql_server = "localhost"; $mysql_user = "root"; $mysql_password = ""; $mysql_db = "bazanovosti"; $mysqli = new mysqli($mysql_server, $mysql_user, $mysql_password, $mysql_db); if ($mysqli->connect_errno) { printf("Konekcija neuspena: %s\n", $mysqli->connect_error); exit(); } $mysqli->set_charset("utf8"); ?>

Ukoliko su MySqli funkcijama dati tane podaci rezultat skripte bi trebalo da bude prazna stranica. MySqli konekcija se zatvara korienjem funkcije close().

1.1 Ubacivanje podataka u bazu (naredba INSERT INTO)


Baza i njoj pripadajue tabele su u poetku prazne nemaju podataka. Osnovna operacija za unos podataka je INSERT INTO. Podaci se preko komandnog panela ubacuju izborom opcije INSERT. Upit kojim se ubacuju podaci u tabelu novosti :
INSERT INTO `novosti` ( `idnovost` , `naslov` , `tekst` ) VALUES ( '', 'Naslov1', 'Ovo je prva vest' ), ( '', 'Naslov2', 'Ovo je druga vest' )

Kod naziva tabele je vrlo bitno napisati njeno ime u pravilom caseu jer su imena baza, tabela i polja case sensitive. Kao to se vidi, u zagradama su navedena polja tabele, ali jedno nedostaje. Polje idnovost nije navedeno i ne radi se o greci u pisanju. Naime, ukoliko se neko polje izostavi u listi njemu se automatski upisuje defaultna vrednost (koja se moe postaviti pri stvaranju tabele). U ovom sluaju je pri stvaranju tabele polju idnovost data auto_increment osobina koja pri svakom insertu tom polju pridruuje po defaultu vrednost veu za 1 od poslednje upisane. Nakon liste polja dolazi VALUES ime se naznaava da sledi lista vrednosti koja se ubacuje u tablicu. Vrednost koja se ubacuje u jedno od polja mora biti na istoj poziciji u listi vrednosti kao i ime polja u koje e se sauvati u listi polja. Kod stvaranja liste polja nije bitan redosled. Bitno je jedino da se ime polja u svojoj listi pozicijom poklapa sa vrednosti u listi vrednosti Jedna od osnovnih funkcionalnosti PHP skriptova je ubacivanje podataka u bazu. Najee se podaci prikupljaju od korisnika. U tekstu sledi primer ubacivanja podataka prikupljenih preko forme.

37

Primer 12: Unos podataka u bazu preko forme (php_mysqli) <!DOCTYPE html> <html> <head> <title>Unos novosti</title> <meta http-equiv="Content-Type" content="text/html; 8" /> </head> <body> <h1>Unos novosti</h1> <hr/> <form method="post" action=""> Naslov : <input type="text" name="naslov" /><br/> Tekst : <textarea name="tekst"></textarea><br/> <input type="submit" name="unos" value="Ubaci" /> </form> <?php if (isset($_POST["unos"])){ //Prikupljanje podataka sa forme if (isset($_POST['naslov'])&&isset($_POST['tekst'])){ $naslov = $_POST['naslov']; $tekst = $_POST['tekst']; //Operacije nad bazom include "konekcija.php"; $sql="INSERT INTO novosti (naslov, tekst) VALUES ('".$naslov."', '". $tekst."')"; if ($mysqli->query($sql)){ echo "<p>Novost je uspeno ubaena</p>"; } else { echo "<p>Nastala je greka pri ubacivanju novosti</p>" . $mysqli>error; } } else { //Ako POST parametri nisu prosleeni echo "Nisu prosleeni parametri!"; } $mysqli->close(); } ?> </body> </html>

charset=utf-

Struktura, tj. logika ove skripte sledi logiku same operacije. Prvi korak je unos podataka u formu, a drugi je ubacivanje tih podataka u bazu. Kao uslov obavljanja prvog ili drugog koraka je postojanje vrednosti u varijabli $_POST["unos"], tj. varijable koju stvara pritisnuti submit taster forme imena unos. U form tagu action atribut nema vrednost. Kada je action atribut definisan na ovaj nain podaci se alju ka stranici na kojoj se nalazi forma. Forma se prikazuje na unosvesti.php pa e se i nakon submit - ovanja forme opet otvarati ista stranica. 38

Drugi korak ubacuje podatke iz forme u bazu. Da bi se moglo neto ubaciti u bazu prvo se mora spojiti na MySql server i odabrati je, to je uraeno u prvom primeru koji je ubaen u dbsproj.php pa je ovde samo ukljuujen.
include "konekcija.php";

Nakon uspenog spajanja na bazu generie se SQL upit:


$sql="INSERT INTO '$_POST[tekst]')"; novosti (naslov, tekst) VALUES ('$_POST[naslov]',

Sledei korak je stvaranje stringa u kojem se nalazi sam SQL upit za unos podataka u tablicu.
$sql="INSERT INTO novosti (naslov, tekst) VALUES ('".$naslov."', '". $tekst."')"; if ($mysqli->query($sql)){ echo "<p>Novost je uspeno ubaena</p>"; } else { echo "<p>Nastala je greka pri ubacivanju novosti</p>" . $mysqli->error; }

Ovo je glavni deo skripte koji obavlja samu komunikaciju sa MySQL serverom, tj. izvrava SQL upit na njemu. Obavlja se pomou query() funkcije. Funkcija query() jedan argument, a to je MySQL upit u obliku stringa. Ovo je funkcija definisana u mysqli klasi, i poziva se preko instanciranog objekta. Na kraju je potrebno zatvoriti konekciju sa bazom, pomou naredbe $mysqli->close(). esto je neophodno da aplikacioni programer zna koji ID je dodeljen unetom zapisu, u sluaju da se koristi automatsko inkrementiranje kod primarnog kljua tabele u koju se ubacuje novi zapis. U tu svrhu se koristi $mysqli->insert_id atribut, koji vraa generisani ID primarnog kljua nakon izvrenja INSERT upita.

1.2 itanje podataka iz baze (naredba SELECT)


Najjednostavniji primer je upit koji pribavlja sve redove iz jedne tabele.
SELECT * FROM novosti

Upit poinje nazivom vrste upita. Ovo je pravilo koje dele svi upiti za manipulaciju podacima u osnovnim oblicima. Nakon imena operacije sledi lista polja koja e se pojaviti u tablici rezultata upita. Zvezdica je skraenica koja govori da e se pribaviti sva polja iz navedenih tabela. Nakon liste polja sledi FROM koji govori da sledi lista tabela iz kojih se podaci pribavljaju. Ovo su ujedno i svi obavezni delovi jednog valjanog SQL SELECT upita pa, ukoliko jedan od njih bude izostavljen MySql e javiti greku i nee obaviti upit. Rezultat upita nije sortiran ni po jednom polju, ali redovi su vraeni po redosledu upisa u bazu, po idnovost polju poto se radi o auto_increment polju koje svakom novom redu daje vrednost veu za 1 od onog prolog.

39

SELECT * FROM novosti ORDER BY idnovost DESC

Da bi rezultati upita bili sortirani dodata je ORDER BY klazula u ovom sluaju na njegov kraj. ORDER BY mora biti propraen imenima polja po kojima se eli sortirati rezultat pa nain sortiranja. U ovom sluaju se radi o polju idnovost DESC (descending) nainom, tj. u opadajuem redosledu. Suprtotno, tj. u rastuem redosledu, se moe sortirati tako da se izostavi DESC ili umesto njega upie ASC (ascending). Ukoliko se izostavi smer sortiranja rezultata podrazumevani smer je uzlazan. Primer 13: Pregled novosti (php_mysqli) <!DOCTYPE html> <html> <head> <title>Pregled novosti</title> <meta http-equiv="Content-Type" content="text/html; charset=utf8" /> </head> <body> <?php include "konekcija.php"; $sql="SELECT naslov, tekst FROM novosti ORDER BY idnovost DESC"; if (!$q=$mysqli->query($sql)){ echo "<p>Nastala je greska pri izvodenju upita</p>" . mysql_query(); exit(); } if ($q->num_rows==0){ echo "Nema novosti"; } else { ?> <table> <tr> <td><b>Naslov</b></td> <td><b>Tekst</b></td> </tr> <?php while ($red=$q->fetch_object()){ ?> <tr> <td><?php echo $red->naslov; ?></td> <td><?php echo $red->tekst; ?></td> </tr> <?php } ?> </table> <?php } $mysqli->close(); ?> </body> </html> 40

SELECT upiti su najopirniji. Razlog tome je prilino oigledan, jer uz obavljanje upita moraju se podaci i pribaviti tj. u ovom sluaju ispisati u obliku tabele. Prva stvar koja se mora uraditi je kreiranje upita.
$sql="SELECT naslov, tekst FROM novosti ORDER BY idnovost DESC";

Za razliku od php_mysql ekstenzije, kod php_mysqli ekstenzije koristi se objektno-orijentisan pristup. Dakle, u fajlu konekcija.php instanciran je objekat i sauvan u promenljivoj $mysqli (naziv ove promenljive naravno moe da bude proizvoljan). Pomou include funkcije, omoguava se pristup ovoj promenljivoj dalje u php skripti. Zatim se izvrava sql upit, pozivanjem funkcije query(), sa prosleenim SQL upitom, kao argumentom funkcije (slino kao u prethodnom primeru). Ukoliko je upit uspeno kreiran, proverava se broj redova, pomou atributa num_rows. Ukoliko ovaj broj nije nula, izvrie se while petlja, koja e imati onoliko iteracija koliko ima redova u tabeli izvrenog SELECT upita. Ovde je najbolje koristiti funkciju fetch_object() koja vraa jedan red tabele u formi objekta. Vrednostima svake kolone se pristupa pomou atributa objekta. Osim funkcije fetch_object(), koja vraa red tabele kao objekat, koriste se i sledee funkcije: fetch_array() vraa red, tj. niz koji se sastojih od svih polja rezultata s tim da je svako polje indeksirano brojem i svojim imenom. fetch_row() takoe vraa niz, sa tom razlikom da u njemu postoje samo numeriki indeksi. fetch_assoc() isto vraa niz, ali u njemu se nalaze samo tekstualno indeksirana polja.

1.1 Brisanje podataka (naredba DELETE)


SQL naredba za brisanje podataka je :
DELETE FROM tabela

U prevodu gornja naredba znai Obrii sve iz tabele imena tabela, ali ovo je oigledno situacija koja e se retko dogaati u nekim realnim skriptama, ve se obino radi o brisanju jednog ili manje grupe podataka. Dalje se vidi kako bi izgledao upit koji obavlja brisanje jedne novosti na osnovu njenog ID-a.
DELETE FROM novosti WHERE idnovost=1

Gornji upit e obrisati samo onu novost koja ima idnovost jednak 1. WHERE slui za naznaavanje da nakon njega slede uslovi pomou kojih se ograniava skup podataka nad kojima e se obaviti neka operacija.
DELETE FROM novosti WHERE naslov = Naslov1

U prevodu, zadato je MySql-u da obrie sve naslove koji imaju vrednost naslov1. Unutar WHERE klazule je mogue kombinovati vie uslova koji ograniavaju skup podataka nad kojima se obavlja operacija kombinovanjem logikim operatorima. WHERE moe shvatiti kao if u PHP-u koji se obavlja nad svakim redom tabele. 41

Takoe, pomou DELETE naredbe nije mogue obrisati pojedinu vrednost unutar nekog polja tabele. Nije mogue obrisati naslov novosti iji je idnovst jednak 1. Za to se koristi UPDATE naredba koja e biti objanjena u sledeem poglavlju. Brisanje se najee implementira u kombinaciji sa prikazom sadraja baze. Prethodni primer e biti proiren tako da pored svake novosti postoji dinamiki generisan link, koji e tu novost da izbrie. Dinamiki generisani linkovi funkcioniu tako to se pored naziva stranice na koju vodi link prosleuje i GET parametar, koji je razliit na osnovu stavke kojoj pripada. Kada se vri linkovanje, ako link poinje upitnikom (?), to znai da e voditi na tekuu php stranicu, a da e njoj proslediti date GET parametre.

Primer 14: Brisanje novosti (php_mysqli) <!DOCTYPE html> <html> <head> <title>Pregled novosti</title> <meta http-equiv="Content-Type" content="text/html; charset=utf8" /> </head> <body> <?php include "konekcija.php"; if (isset ($_GET['akcija']) && isset ($_GET['idnovost'])){ $akcija = $_GET['akcija']; $id = $_GET['idnovost']; switch ($akcija){ case "brisanje": $upit = "DELETE FROM novosti WHERE idnovost = ".$id; if (!$q=$mysqli->query($upit)){ echo "Nastala je greska pri izvodenju upita<br/>" . mysql_query(); die(); } else { echo "<p>Brisanje zapisa je uspeno!</p>"; } break; default: echo "<p>Nepostojea akcija!</p>"; break; } } $sql="SELECT idnovost, naslov, tekst FROM novosti"; if (!$q=$mysqli->query($sql)){ echo "Nastala je greska pri izvodenju upita<br>" . mysql_query(); die(); } if ($q->num_rows==0){ echo "Nema novosti"; } else { ?> <table> <tr> 42

<td><b>Naslov</b></td> <td><b>Tekst</b></td> <td><b>Akcija</b></td> </tr> <?php while ($red=$q->fetch_object()){ ?> <tr> <td><?php echo $red->naslov; ?></td> <td><?php echo $red->tekst; ?></td> <td><a href="?akcija=brisanje&idnovost=<?php echo $red->idnovost; ? >">Brisanje</a></td> </tr> <?php } ?> </table> <?php } $mysqli->close(); ?> </body> </html>

Prethodnom primeru, gde je bio objanjen prikaz podataka iz baze, dodata je funkcionalnost brisanja. SQL upit za listanje podataka morao je biti malo izmenjen, poto e biti neophodno korienje atributa idnovost, za generisanje dinamikog linka za brisanje novosti. Ispod ukljuivanja fajla konekcija.php, proverava se da li je prosleen GET parametar akcija i idnovost. Ukoliko jesu prosleeni, radi jednostavnost, definiu se promenljive akcija i id na osnovu prosleenih GET parametara, pa se zatim proverava vrednost parametra akcija pomou switch-case bloka naredbi. Ovde je mogue koristiti i if..else, meutim switch-case je bolje reenje, zato to moe da postoji vie razliitih akcija. Ukoliko je vrednost GET parametra akcija brisanje, kree se sa brisanjem.
$upit = "DELETE FROM novosti WHERE idnovost = ".$id; if (!$q=$mysqli->query($upit)){ echo "Nastala je greska pri izvodenju upita<br/>" . mysql_query(); die(); } else { echo "<p>Brisanje zapisa je uspeno!</p>"; }

Izvravanje upita je vrlo slino kao kod INSERT upita. Dovoljno je obaviti upit pomou mysql_query() funkcije. ak nije obavezno ubaciti njen rezultat u neku varijablu poto ne postoji potreba za njenim korienjem kasnije u skripti. Da bi proverili da li je novost stvarno obrisana, moe se koristiti mysqli atribut affected_rows. Atribut vraa broj redova koji su bili zahvaeni poslednjom operacijom. Moe se koristiti samo nakon DELETE, UPDATE i INSERT upita, tj. upita koji vre izmene nad podacima tabela. Uz upotrebu ovog atributa, glavni deo prethodnog primera izgledao bi ovako:
$upit = "DELETE FROM novosti WHERE idnovost = ".$id; if (!$q=$mysqli->query($upit)){

43

echo "Nastala je greska pri izvodenju upita<br/>" . mysql_query(); die(); } else { if ($mysqli->affected_rows > 0 ){ echo "<p>Brisanje zapisa je uspeno!</p>"; } else { echo "<p>Ni jedan zapis nije obrisan!</p>"; } }

Deo koda:
<td><a href="?akcija=brisanje&idnovost=<?php echo $red->idnovost; ? >">Brisanje</a></td>

se ispisuje u svakom prolazu petlje kroz red u tabeli. Odabirom opcije Brisanje ide se na link upisan u href atributu. U ovom sluaju to je isti onaj fajl koji se izvrava. Dodatni parameter je idnovost, koji dobija vrednost u zavisnosti od toga koji red je izabran.

1.2 Izmena postojeih podataka (naredba UPDATE)


Za izmenu podataka se koristi UPDATE naredba.
UPDATE novosti SET naslov="Novi naslov"

Kao i svi ostali upiti do sada i ovaj poinje navoenjem imena operacije koja se izvodi. Ovog puta je odmah nakon naziva naredbe navedena tabela u kojoj se ele napraviti izmene. Nakon imena tabele slede SET koji govori da slede parovi imena polja tabele sa pridruenim novim vrednostima. Nakon izvravanja gornjeg primera bi u svim redovima tabele naslov bio promenjen u Novi naslov. Ukoliko je potrebno izmeniti vie polja istovremeno, to bi bilo uinjeno ovakvim upitom:
UPDATE novosti SET naslov="Novi naslov", tekst="abcdefghijk"

Znai, za izvoenje izmena vrednosti u vie polja potrebno je dva naziva polja sa pridruenim vrednostima odvojiti zarezom. Normalno, izmena vrednosti svim redovima neke tabele je vrlo retka pojava u realnim skriptama. Iz tog razloga je mogue pomou WHERE klazule ograniiti skup podataka nad kojima se vri izmena. U konkretnom primeru bi to izgledalo od prilike ovako :
UPDATE novosti idnovost=1 SET naslov="Novi naslov", tekst="abcdefghijk" WHERE

Ovim upitom je izmenjen naslov i tekst novosti koja ima ID jednak jedan. Naredni primer se takoe nadograuje na prethodni. Potrebno je definisati dve nove akcije u switch-case bloku naredbi. U pitanju je akcija izmena_forma, koja prikazuje formu za izmenu izabranog reda i koja se poziva pomou generisanog dinamikog linka i akcija izmena, koja vri konkretnu UPDATE operaciju nad bazom (poziva se klikom na taster submit na formi prikazanoj pomou akcije izmena_forma). Dinamiki link za izmenu se generie na istovetan nain kao i dinamiki link za brisanje, uveden u prethodnom primeru. Naravno, u okviru jednog PHP fajla mogue je kombinovati GET i POST parametre. Pomou GET parametra

44

e se uvek prosleivati vrednost akcije i vrednost parametra idnovost, a pomou POST parametara prosleivae se nove vrednosti nakon izmene. Primer 15: Izmena novosti (php_mysqli) <!DOCTYPE html> <html> <head> <title>Pregled novosti</title> <meta http-equiv="Content-Type" content="text/html; charset=utf8" /> </head> <body> <?php include "konekcija.php"; if (isset ($_GET['akcija']) && isset ($_GET['idnovost'])){ $akcija = $_GET['akcija']; $id = $_GET['idnovost']; switch ($akcija){ case "brisanje": $upit = "DELETE FROM novosti WHERE idnovost = ".$id; if (!$q=$mysqli->query($upit)){ echo "Nastala je greska pri izvodenju upita<br/>" . mysql_query(); die(); } else { echo "<p>Brisanje zapisa je uspeno!</p>"; } break; case "izmena_forma": ?> <h1>Izmena novosti</h1> <hr/> <form method="post" action="?akcija=izmena&idnovost=<?php echo $_GET['idnovost'];?>"> Naslov : <input type="text" name="naslov" /><br/> Tekst : <textarea name="tekst"></textarea><br/> <input type="submit" name="unos" value="Ubaci" /> </form> <?php break; case "izmena": if (isset ($_POST['naslov']) && isset ($_POST['tekst'])){ $naslov = $_POST['naslov']; $tekst = $_POST['tekst']; $upit="UPDATE novosti SET naslov='". $naslov ."', tekst='" . $tekst . "' WHERE idnovost=". $id; if ($mysqli->query($upit)){ if ($mysqli->affected_rows > 0 ){ echo "<p>Novost je uspeno izmenjena.</p>"; } else { echo "<p>Novost nije izmenjena.</p>"; } } else { 45

echo "<p>Nastala je greka pri izmeni novosti</p>" . mysql_error(); } } else { echo "<p>Nisu prosleeni parametri za izmenu"; } break; default: echo "<p>Nepostojea akcija!</p>"; break; } } $sql="SELECT idnovost, naslov, tekst FROM novosti"; if (!$q=$mysqli->query($sql)){ echo "Nastala je greska pri izvodenju upita<br>" . mysql_query(); die(); } if ($q->num_rows==0){ echo "Nema novosti"; } else { ?> <h1>Prikaz novosti</h1> <hr/> <table> <tr> <td><b>Naslov</b></td> <td><b>Tekst</b></td> <td><b>Akcija</b></td> </tr> <?php while ($red=$q->fetch_object()){ ?> <tr> <td><?php echo $red->naslov; ?></td> <td><?php echo $red->tekst; ?></td> <td><a href="?akcija=izmena_forma&idnovost=<?php echo $red>idnovost; ?>">Izmena</a></td> <td><a href="?akcija=brisanje&idnovost=<?php echo $red->idnovost; ? >">Brisanje</a></td> </tr> <?php } ?> </table> <?php } $mysqli->close(); ?> </body> </html>

Kao i u dosadanjim primerima, na samom poetku skripte je ukljuen konekcija.php. 46

Dodata je nova akcija izmena_forma. Ova akcija takoe prosleuje id novosti preko GET parametra i ukoliko je pozvana, prikazuje formu za izmenu. Generisan je dinamiki link ka ovoj akciji, na slian nain kao dinamiki link za brisanje. Klikom na taster submit, poziva se akcija izmena i prosleuje se parametar idnovost, koji je takoe prikupljen pomou GET metode. Ova akcija proverava da li su prosleeni POST parametri sa novim vrednostima, prikupljeni iz forme. Ukoliko jesu, izvrava se upit koji vri izmenu u bazi: $upit="UPDATE novosti SET naslov='". $naslov ."', tekst='" . $tekst . "' WHERE idnovost=". $id; if (mysql_query($upit)){ if (mysql_affected_rows() > 0 ){ echo "<p>Novost je uspeno izmenjena.</p>"; } else { echo "<p>Novost nije izmenjena.</p>"; } } else { echo "<p>Nastala je greka pri izmeni novosti</p>" . mysql_error(); } U praksi se najee menja samo jedno polje, a retko kada sva polja. Navedeni primer ne prosleuje postojee vrednosti polja u formu za izmenu, ime se poveava mogunost sluajne izmene nekog polja, odnosno mogunost da se izbrie sadraj nekog polja. Uvek bi trebalo proslediti vrednost tekueg polja iz baze u formu za izmenu polja. Sledei primer pokazuje kako je to mogue uraditi: Primer 16: Izmena novosti poboljana verzija (php_mysqli) <!DOCTYPE html> <html> <head> <title>Pregled novosti</title> <meta http-equiv="Content-Type" content="text/html; charset=utf8" /> </head> <body> <?php include "konekcija.php"; if (isset ($_GET['akcija']) && isset ($_GET['idnovost'])){ $akcija = $_GET['akcija']; $id = $_GET['idnovost']; switch ($akcija){ case "brisanje": $upit = "DELETE FROM novosti WHERE idnovost = ".$id; if (!$q=$mysqli->query($upit)){ echo "Nastala je greska pri izvodenju upita<br/>" . mysql_query(); die(); } else { echo "<p>Brisanje zapisa je uspeno!</p>"; } break; case "izmena_forma": 47

$upit="SELECT idnovost, naslov, tekst FROM novosti WHERE idnovost=". $id; if (!$q=$mysqli->query($upit)){ echo "<p>Nastala je greska pri izvodenju upita</p>" . mysql_query(); die(); } else { if ($q->num_rows!=1){ echo "<p>Nepostojea novost.</p>"; } else { $novost = $q->fetch_object(); $naslov = $novost->naslov; $tekst = $novost->tekst; ?> <h1>Izmena novosti</h1> <hr/> <form method="post" action="?akcija=izmena&idnovost=<?php echo $_GET['idnovost'];?>"> Naslov : <input type="text" name="naslov" value="<?php echo $naslov;?>"/><br/> Tekst : <textarea name="tekst"><?php echo $tekst;?></textarea><br/> <input type="submit" name="unos" value="Ubaci" /> </form> <?php } } break; case "izmena": if (isset ($_POST['naslov']) && isset ($_POST['tekst'])){ $naslov = $_POST['naslov']; $tekst = $_POST['tekst']; $upit="UPDATE novosti SET naslov='". $naslov ."', tekst='" . $tekst . "' WHERE idnovost=". $id; if ($mysqli->query($upit)){ if ($mysqli->affected_rows > 0 ){ echo "<p>Novost je uspeno izmenjena.</p>"; } else { echo "<p>Novost nije izmenjena.</p>"; } } else { echo "<p>Nastala je greka pri izmeni novosti</p>" . mysql_error(); } } else { echo "<p>Nisu prosleeni parametri za izmenu"; } break; default: echo "<p>Nepostojea akcija!</p>"; break; } } $sql="SELECT idnovost, naslov, tekst FROM novosti"; if (!$q=$mysqli->query($sql)){ echo "Nastala je greska pri izvodenju upita<br>" . mysql_query(); 48

die(); } if ($q->num_rows==0){ echo "Nema novosti"; } else { ?> <h1>Prikaz novosti</h1> <hr/> <table> <tr> <td><b>Naslov</b></td> <td><b>Tekst</b></td> <td><b>Akcija</b></td> </tr> <?php while ($red=$q->fetch_object()){ ?> <tr> <td><?php echo $red->naslov; ?></td> <td><?php echo $red->tekst; ?></td> <td><a href="?akcija=izmena_forma&idnovost=<?php echo $red>idnovost; ?>">Izmena</a></td> <td><a href="?akcija=brisanje&idnovost=<?php echo $red->idnovost; ? >">Brisanje</a></td> </tr> <?php } ?> </table> <?php } $mysqli->close(); ?> </body> </html>

Dakle, jedina izmena u odnosu na prethodni primer jeste ubacivanje i izvravanje SELECT upita u akciji izmena_forma. Proverava se da li postoji tano jedna vrednost novosti sa datim id-om i ukoliko postoji, prikazuju se podaci u bazi. Ovde nije neophodno korienje while petlje, poto je u pitanju samo jedna vrednost. Konano, ukoliko bi se primer ubacivanja novog zapisa ubacio u ovaj fajl, dobio bi se primer sa svim CRUD operacijama u jednom fajlu. Za to je potrebno definisati novu akciju unos. Poto ova akciji nisu potrebni dodatni parametri, kao to je idnovost, potrebno ju je definisati van swich-case bloka (poto se on izvrava nakon provere GET parametara akcija i idnovost). U okviru akcije, mogu se definisati i forma i samo izvravanje INSERT operacije nad bazom. Dovoljno je iskopirati deo koda iz primera za ubacivanje zapisa. Naravno, potrebno je promeniti action atribut prilikom definisanje forme, tako da bude ?akcija=unos.

49

Primer 17: Sve CRUD operacije u jednom fajlu (php_mysqli) <!DOCTYPE html> <html> <head> <title>Pregled novosti</title> <meta http-equiv="Content-Type" content="text/html; 8" /> </head> <body> <?php include "konekcija.php"; if (isset ($_GET['akcija'])){ if ($_GET['akcija'] == 'unos'){ ?> <h1>Unos novosti</h1> <hr/> <form method="post" action="?akcija=unos"> Naslov : <input type="text" name="naslov" /><br/> Tekst : <textarea name="tekst"></textarea><br/> <input type="submit" name="unos" value="Ubaci" /> </form> <?php if (isset($_POST["unos"])){ //Prikupljanje podataka sa forme if (isset($_POST['naslov'])&&isset($_POST['tekst'])){ $naslov = $_POST['naslov']; $tekst = $_POST['tekst']; //Operacije nad bazom include "konekcija.php"; $sql="INSERT INTO novosti (naslov, tekst) VALUES ('".$naslov."', '". $tekst."')"; if ($mysqli->query($sql)){ echo "<p>Novost je uspeno ubaena.</p>"; } else { echo "<p>Nastala je greka pri ubacivanju novosti</p>" . mysql_error(); } } else { //Ako POST parametri nisu prosleeni echo "Nisu prosleeni parametri!"; } } } } if (isset ($_GET['akcija']) && isset ($_GET['idnovost'])){ $akcija = $_GET['akcija']; $id = $_GET['idnovost']; switch ($akcija){ case "brisanje": 50

charset=utf-

$upit = "DELETE FROM novosti WHERE idnovost = ".$id; if (!$q=$mysqli->query($upit)){ echo "Nastala je greska pri izvodenju upita<br/>" . mysql_query(); die(); } else { echo "<p>Brisanje zapisa je uspeno!</p>"; } break; case "izmena_forma": $upit="SELECT idnovost, naslov, tekst FROM novosti WHERE idnovost=". $id; if (!$q=$mysqli->query($upit)){ echo "<p>Nastala je greska pri izvodenju upita</p>" . mysql_query(); die(); } else { if ($q->num_rows!=1){ echo "<p>Nepostojea novost.</p>"; } else { $novost = $q->fetch_object(); $naslov = $novost->naslov; $tekst = $novost->tekst; ?> <h1>Izmena novosti</h1> <hr/> <form method="post" action="?akcija=izmena&idnovost=<?php echo $_GET['idnovost'];?>"> Naslov : <input type="text" name="naslov" value="<?php echo $naslov;?>"/><br/> Tekst : <textarea name="tekst"><?php echo $tekst;?></textarea><br/> <input type="submit" name="unos" value="Ubaci" /> </form> <?php } } break; case "izmena": if (isset ($_POST['naslov']) && isset ($_POST['tekst'])){ $naslov = $_POST['naslov']; $tekst = $_POST['tekst']; $upit="UPDATE novosti SET naslov='". $naslov ."', tekst='" . $tekst . "' WHERE idnovost=". $id; if ($mysqli->query($upit)){ if ($mysqli->affected_rows > 0 ){ echo "<p>Novost je uspeno izmenjena.</p>"; } else { echo "<p>Novost nije izmenjena.</p>"; } } else { echo "<p>Nastala je greka pri izmeni novosti</p>" . mysql_error(); } } else { echo "<p>Nisu prosleeni parametri za izmenu"; } 51

break; default: echo "<p>Nepostojea akcija!</p>"; break; } } $sql="SELECT idnovost, naslov, tekst FROM novosti"; if (!$q=$mysqli->query($sql)){ echo "Nastala je greska pri izvodenju upita<br>" . mysql_query(); die(); } if ($q->num_rows==0){ echo "Nema novosti"; } else { ?> <h1>Prikaz novosti</h1> <hr/> <table> <tr> <td><b>Naslov</b></td> <td><b>Tekst</b></td> <td><b>Akcija</b></td> </tr> <?php while ($red=$q->fetch_object()){ ?> <tr> <td><?php echo $red->naslov; ?></td> <td><?php echo $red->tekst; ?></td> <td><a href="?akcija=izmena_forma&idnovost=<?php echo $red>idnovost; ?>">Izmena</a></td> <td><a href="?akcija=brisanje&idnovost=<?php echo $red->idnovost; ? >">Brisanje</a></td> </tr> <?php } ?> </table> <?php } $mysqli->close(); ?> <p><a href="?akcija=unos">Unos novosti</a></p> </body> </html>

52

1.3 Rad sa transakcijama

Transakcija je jedno izvrenje neke logike jedinice posla, jedno izvrenje neke logike celine jednog programa ili jedno izvrenje celog programa. Svaka transakcija ima osobine atomnosti, konzistentnosti, izolacije i trajnosti.1 MySQL sistem upravljanja podacima podrava rad sa transakcijama, ali samo pri korienju InnoDB storage engine-a. Transakcija moe predstavljati blok SQL upita, koji moraju da se izvre sukcesivno. Prilikom izvravanja transakcije, baza podataka se zakljua i niko ne moe da vri operacije nad njom dok se transakcija ne izvri. Sreom, vreme izvravanja transakcije meri se u milisekundama. Za izvravanje transakcije, koriste se instrukcije COMMIT i ROLLBACK. Instrukcija COMMIT slui za izvravanje transakcije, a ROLLBACK za vraanje baze na prethodno stanje ukoliko se transakcija ne izvri uspeno. Pri radu sa transakcijama, poeljno je prvo iskljuiti opciju AUTOCOMMIT. Ona slui za automatsko izvravanja transakcija i eventualno vraanje na prethodno stanje u sluaju greke. Na primer, jedna transakcija moe da predstavlja ubacivanje vie redova u tabelu neke baze:

Primer 18: Rad sa transakcijama (php_mysqli) <!DOCTYPE html> <html> <head> <title>Primer transakcije</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> </head> <body> <h1>Primer transakcije</h1> <hr/> <?php include "konekcija.php"; $mysqli->autocommit(FALSE); $q1 = $mysqli->query("INSERT INTO novosti (naslov, tekst) VALUES ('Prva vest', 'Tekst prve vesti')"); $q2 = $mysqli->query("INSERT INTO novosti (naslov, tekst) VALUES ('Druga vest', 'Tekst druge vesti')"); $q3 = $mysqli->query("INSERT INTO novosti (naslov, tekst) VALUES ('Trea vest', 'Tekst tree vesti')"); if ($q1 && $q2 && $q3){ $mysqli->commit(); echo "<p>Novosti su uspeno ubaene!</p>"; } else { $mysqli->rollback(); echo "<p>Novosti nisu ubaene!</p>"; } $mysqli->close();
1 Branislav Lazarevi, Zoran Marjanovi, Nenad Anii, Slaan Babarogi Baze podataka, FON, Beograd, 2006.

53

?> </body> </html> Nakon iskljuivanja AUTOCOMMIT opcije, treba izvriti sve upite nad bazom koji ine transakciju. Svaki upit treba sauvati kao promenljivu. Ukoliko je upit uspeno izvren, tada je vrednost promenljive TRUE. Nakon izvravanja upita, potrebno je proveriti da li su svi upiti koji ine transakciju uspeno izvreni, odnosno da li je vrednost promenljivih koje su sauvale vrednost upita TRUE. Ukoliko je to sluaj, potrebno je potvrditi uspeno izvrenje transakcije funkcijom commit(). Ako je bar jedan upit nekorektan, tada treba vratiti bazu na poetno stanje korienjem funkcije rollback(). U datom primeru, svi upiti su korektni, pa e se izvriti transakcija. Ukoliko se izvri izmena bilo kog upita i ubaci neka tipografska greka (npr. INSET umesto INSERT), izvrie se rollback() i promene nijednog upita nee biti sauvane.

54

1.4 Pripremljeni upiti


Pripremljene naredbe (prepared statements) programerima olakavaju rad sa SQL upitima. Ideja je da se umesto umetnute vrednosti kod INSERT, UPDATE ili DELETE upita ubace upitnici, a nakon pripreme nepotpunog upita da se upitnici poveu sa nekim PHP promenljivama, posle ega se konano izvrava upit. Pripremljene naredbe su vrsta ablona (templejta) koji slui za jednostavniji rad sa upitima. Njihova primena je posebno znaajna kod manipulacije vie redova u tabeli. Za pripremu upita, koristi se funkcija mysqli klase prepare(). Ova funkcija prima jedan ulazni parametar, a to je pripremljeni SQL upit u vidu stringa. Na primer:
$upit_string = "INSERT INTO novosti (naslov, tekst) VALUES (?, ?)"; $upit = $mysqli->prepare ($upit_string);

Ovde se moe primetiti da u delu upita VALUES stoje upitnici, umesto pravih vrednosti koje bi trebalo ubaciti u bazu. Zatim je potrebno izvriti povezivanje parametara i upitnika. To se radi pomou funkcije bind_param(). Ova funkcija prima najmanje dva ulazna argumenta. Prvi argument je string koji sadri slova koja predstavljaju tip vrednosti parametra. Ukoliko ima jedan upitnik u pripremljenom upitu, trebalo bi da ovde stoji jedno slovo, a u sluaju da na primer ima pet upitnika, ovde treba da stoji pet slova bez razmaka. Mogui tipovi podataka (odnosno slova) prikazani su u tabeli: Slovo i d s b Tip podatka Integer (celobrojna vrednost) Double (decimalna vrednost) String Blob (binarni tip podataka, alje se u paketima)

Tabela 5: Tipovi podataka za pripremljene upite

Drugi i dalji argumenti predstavljaju promenljive koje se povezuju (bind) sa znakovima pitanja pripremljenog upita. Neophodno je da se promenljive unose redom. Dakle, prva promenljiva (drugi argument funkcije) treba da odgovara prvom znaku pitanja, druga promenljiva (trei argument funkcije) drugom upitniku itd. Sledei blok naredbi:
$naslov = "Neki naslov"; $tekst = "Tekst novosti"; $upit->bind_param("ss", $naslov, $tekst);

definie promenljivu $naslov i $tekst, a zatim ih povezuje sa pripremljenim upitom, korienjem funkcije bind_param(). Prvi argument "ss" oznaava da su oba parametra tipa string. Sve ove naredbe ekvivalentne su upitu bez pripreme:
$upit_string = "INSERT INTO novosti (naslov, tekst) VALUES ('Neki naslov', 'Tekst novosti')"; $upit = $mysqli->query ($upit_string);

55

U sledeem primeru, obraen je jednostavan sluaj korienja pripremljenog upita na primeru iste baze:

Primer 19: Pripremljeni upit (php_mysqli) <!DOCTYPE html> <html> <head> <title>Primer pripremljenih upita</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> </head> <body> <h1>Primer pripremljenih upita</h1> <hr/> <?php include "konekcija.php"; //Pripremanje upita $upit_string = "INSERT INTO novosti (naslov, tekst) VALUES (?, ?)"; $upit = $mysqli->prepare ($upit_string); //Definisanje promenljivih ije vrednosti e biti ubaene u bazu $naslov = "Neki naslov"; $tekst = "Tekst novosti"; //Povezivanje parametara sa promenljivama $upit->bind_param("ss", $naslov, $tekst); $upit->execute(); $mysqli->close(); ?> </body> </html>

56

2 Ekstenzija php_pdo
PHP Data Objects predstavlja PHP ekstenziju koja definie konzistentan interfejs za pristup bazama podataka. PDO zapravo predstavlja svojevrsnog database brokera za programski jezik PHP. Njime je omoguen rad sa vie razliitih sistema za upravljanja podacima. Podrani su MySQL, Microsoft SQL Server, ODBC, SQLite i dr. Drugim reima, PDO obezbeuje sloj apstrakcije pristupu podataka, to znai da se kod svih sistema za upravljanje podacima koriste iste funkcije za pokretanje upita i uzimanje podataka. PDO ne obezbeuje apstrakciju samih podataka, to znai da ne apstrahuje same upite. Napredniji SQL upiti mogu malo da variraju kod razliitih database servera, ali su osnovni SQL upiti uvek isti. Ekstenzija php_pdo radi sa drajverima specijalno pisanim za ovu ekstenziju. To znai da npr. MySQL koristi jedan drajver, SQLite drugi drajver i sl. Za rad sa PDO treba ukljuiti odgovarajuu ekstenziju. Npr. za PDO sa podrkom za MySQL, treba ukljuiti php_pdo_mysql, za rad sa SQLite bazom php_pdo_sqlite i dr. Za konekciju sa bazom pomou PDO-a, potrebno je kreirati novi objekat klase PDO. Prvi parametar konstruktora je uvek konekcioni string, drugi parametar je korisniko ime za pristup bazi, trei parametar je lozinka za pristup bazi, a etvrti parametar je niz sa dodatnim parametrima podeavanja konekcije. Prvi parametar je uvek obavezan, a svi ostali su opcioni. Konekcioni string (DSN, data source name) sadri informacije neophodne za pristup bazi. On je specifian za sam database server i razlikuje se za MySQL, MSSQL, SQLite i dr. Uvek sadri tip servera baze podataka, IP adresu ili hostname database servera i naziv baze koja treba da se izabere. Na primer, konekcioni string za MySQL bie:
$db = new PDO('mysql:host=localhost;dbname=bazanovosti', 'root', '');

Ovim konekcionim stringom, kreira se konekcija ka MySQL serveru koji se nalazi na lokalnom raunaru, pristupa se bazi bazanovosti, korisniko ime MySQL servera je root, a lozinka je prazna (podrazumevano MySQL podeavanje). Za zatvaranje konekcije ka bazi, dodeljuje se vrednost null promenljivoj $db:
$db = null;

Da bi se proverilo da li je povezivanje sa bazom uspeno, trebalo bi da se izvri hvatanje PDOException izuzetka. On nastupa samo u sluaju da povezivanje nije uspelo (npr. Server ili baza ne postoje). Sledei primer prikazuje fajl konekcija.php, ali ovim putem sa korienjem PDO ekstenzije sa MySQL bazom podataka: Primer 20: Povezivanje sa bazom podataka (php_pdo) Pomou fajla konekcija.php se vri povezivanje sa serverom na kojem je smetena baza. <?php try{ 57

$db_server = "localhost"; $db_user = "root"; $db_password = ""; $db_baza = "bazanovosti"; $db = new PDO('mysql:host='.$db_server.';dbname='.$db_baza, $db_user, $db_password); $db->exec ("SET NAMES utf8"); $db->exec ("SET CHARACTER SET utf8"); $db->exec ("SET COLLATION_CONNECTION='utf8_unicode_ci'"); } catch (PDOException $e){ echo "<p>Neuspeno povezivanje sa bazom!</p>".$e; exit(); } ?>

Za podeavanje utf-8 kodnog rasporeda, koristi se izvravanje odgovarajuih SQL upita, kao i kod php_mysql ekstenzije. Bitno je navesti da se ti upiti izvravaju odmah posle konekcije, pa ih je mogue uvesti u konekcioni fajl. Za izvravanje upita kod PDO-a postoje dve naredbe, exec() i query(). Obe izvravaju SQL upit na serveru i ulazni parametar je SQL upit. Njihova razlika je u povratnoj vrednosti. Funkcija exec() vraa broj redova na koje se odnosi promena nakon upita (affected_rows), a query() vraa rezultat SELECT upita (resultset). Dakle, exec() bi trebalo koristiti kod INSERT, UPDATE i DELETE naredbi, a query() kod SELECT naredbe. Za uzimanje rezultata iz baze, koristi se funkcija fetch() koja kao argument prima eljeni stil preuzimanja podataka. Funkcija fetch() je vezana za objekat klase PDOStatement. Ovaj objekat se dobija nakon izvrenog upita. Npr:
$sql="SELECT idnovost, naslov, tekst FROM novosti"; $upit = $db->query($sql);

Promenljiva $upit je ovde tipa PDOStatement. U narednoj tabeli, prikazane su mogue vrednosti argumenta funkcije fetch(): Argument PDO::FETCH_ASSOC PDO::FETCH_BOTH PDO::FETCH_BOUND PDO::FETCH_CLASS PDO::FETCH_INTO PDO::FETCH_LAZY PDO::FETCH_NUM PDO::FETCH_OBJ Znaenje Vraa asocijativni niz Vraa i numeriki i asocijativni niz Vraa TRUE i dodeljuje vrednosti kolona iz resultset-a PHP varijablama koje su bile povezane preko bindColumn() metode. Koristi se samo zajedno sa pripremljenim upitima. Vraa instancu traene klase Aurira postojeu instancu traene klase, mapira kolone resultset-a sa atributima u klasi Kombinuje PDO::FETCH_BOTH i PDO::FETCH_OBJ Vraa numeriki niz Vraa podatke kao anonimni objekat
Tabela 6: PDO tipovi podataka

Naredni primer pokazuje primenu CRUD operacija, ali korienjem PDO-a:

58

Primer 21: Sve CRUD operacije u jednom fajlu (php_pdo) <!DOCTYPE html> <html> <head> <title>Pregled novosti</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> </head> <body> <?php include "konekcija.php"; if (isset ($_GET['akcija'])){ if ($_GET['akcija'] == 'unos'){ ?> <h1>Unos novosti</h1> <hr/> <form method="post" action="?akcija=unos"> Naslov : <input type="text" name="naslov" /><br/> Tekst : <textarea name="tekst"></textarea><br/> <input type="submit" name="unos" value="Ubaci" /> </form> <?php if (isset($_POST["unos"])){ //Prikupljanje podataka sa forme if (isset($_POST['naslov'])&&isset($_POST['tekst'])){ $naslov = $_POST['naslov']; $tekst = $_POST['tekst']; //Operacije nad bazom include "konekcija.php"; $sql="INSERT INTO novosti (naslov, tekst) VALUES ('".$naslov."', '".$tekst."')"; if ($db->exec($sql)){ echo "<p>Novost je uspeno ubaena.</p>"; } else { echo "<p>Nastala je greka pri ubacivanju novosti</p>"; } } else { //Ako POST parametri nisu prosleeni echo "Nisu prosleeni parametri!"; } } } } if (isset ($_GET['akcija']) && isset ($_GET['idnovost'])){ $akcija = $_GET['akcija']; $id = $_GET['idnovost']; switch ($akcija){ 59

case "brisanje": $upit = "DELETE FROM novosti WHERE idnovost = ".$id; if (!$q=$db->exec($upit)){ echo "Nastala je greska pri izvodenju upita<br/>"; die(); } else { echo "<p>Brisanje zapisa je uspeno!</p>"; } break; case "izmena_forma": $upit="SELECT idnovost, naslov, tekst FROM novosti WHERE idnovost=".$id; if (!$q=$db->query($upit)){ echo "<p>Nastala je greska pri izvodenju upita</p>"; die(); } else { $broj_redova = $q->rowCount(); if ($broj_redova!=1){ echo "<p>Nepostojea novost.</p>"; } else { $novost = $q->fetch(PDO::FETCH_OBJ); $naslov = $novost->naslov; $tekst = $novost->tekst; ?> <h1>Izmena novosti</h1> <hr/> <form method="post" action="?akcija=izmena&idnovost=<?php echo $_GET['idnovost'];?>"> Naslov : <input type="text" name="naslov" value="<?php echo $naslov;?>"/><br/> Tekst : <textarea name="tekst"><?php echo $tekst;?></textarea><br/> <input type="submit" name="unos" value="Ubaci" /> </form> <?php } } break; case "izmena": if (isset ($_POST['naslov']) && isset ($_POST['tekst'])){ $naslov = $_POST['naslov']; $tekst = $_POST['tekst']; $upit="UPDATE novosti SET naslov='". $naslov ."', tekst='" . $tekst . "' WHERE idnovost=". $id; if ($br_redova = $db->exec($upit)){ if ($br_redova > 0 ){ echo "<p>Novost je uspeno izmenjena.</p>"; } else { echo "<p>Novost nije izmenjena.</p>"; } } else { echo "<p>Nastala je greka pri izmeni novosti</p>" ; } } else { echo "<p>Nisu prosleeni parametri za izmenu"; } break; default: 60

echo "<p>Nepostojea akcija!</p>"; break; } } $sql="SELECT idnovost, naslov, tekst FROM novosti"; $upit = $db->query($sql); $broj_redova = $upit->rowCount(); if ($broj_redova == 0){ echo "<p>Nema novosti!</p>"; } else { ?> <h1>Prikaz novosti</h1> <hr/> <table> <tr> <td><b>Naslov</b></td> <td><b>Tekst</b></td> <td><b>Akcija</b></td> </tr> <?php while ($red= $upit->fetch(PDO::FETCH_OBJ)){ ?> <tr> <td><?php echo $red->naslov; ?></td> <td><?php echo $red->tekst; ?></td> <td><a href="?akcija=izmena_forma&idnovost=<?php echo $red->idnovost; ? >">Izmena</a></td> <td><a href="?akcija=brisanje&idnovost=<?php echo $red->idnovost; ?>">Brisanje</a></td> </tr> <?php } ?> </table> <?php } $db = null; ?> <p><a href="?akcija=unos">Unos novosti</a></p> </body> </html>

61

3 PHP i ODBC
U PHP u moe da se napravi i ODBC ( Open DataBase Connectivity) konekcija, tj. PHP skripte mogu da se poveu sa nekom drugom bazom podataka , npr. Microsoft Access preko ODBC drajvera. Pre svega, pod Windows operativnim sistemom, treba da se kreira ODBC konekcija. U Control Panel u, u jeziku Administrative Tools, dva puta se klikne na Data Sources (ODBC). U okviru jezika (tab) System DNS, klikne se na ADD i izabere se odgovarajui ODBC drajver. Kada se izabere ODBC drajver, klikne se na dugme Finish. Nakon toga ostaje da se izabere lokacija baze podataka na koju e se PHP skripta povezati preko ODBC drajvera klikom na Select tab. Izabere se Data Source Name (DSN) eljene baze podataka. Klikom na dugme Ok, ODBC konekcija je kreirana. U narednoj tabeli dat je kratak pregled ODBC funkcija u PHP u: Naziv Funkcije odbc_connect odbc_result odbc_exec Odbc_fetch_row Odbc_close Sintaksa odbc_connect(ime korisnicko ime, sifra) Opis baze, Ova funkcija slui za povezivanje na bazu preko ODBC drajvera. odbc_result(broj polja, ime) Ova funkcija slui za itanje podataka iz polja baze odbc_exec(promenljiva u koju Slui za itanje upita je zapisan upit, promenljiva za preko odbc drajvera odbc konekciju) Odbc_fetch_row(promenljiva) ita podatke iz redova baze Odbc_close() Slui za zatvaranje odbc konekcije
Tabela 7: ODBC funkcije u PHP-u

62

Indeks primera
Primer 1: Kreiranje nove baze podataka (PhpMyAdmin)........................................................7 Primer 2: Kreiranje tabele (PhpMyAdmin)..............................................................................9 Primer 3: Kreiranje nove baze podataka (SQL)....................................................................11 Primer 4: Povezivanje sa bazom podataka (php_mysql)......................................................17 Primer 5: Unos podataka u bazu preko forme (php_mysql)..................................................18 Primer 6: Pregled novosti (php_mysql).................................................................................20 Primer 7: Brisanje novosti (php_mysql)................................................................................23 Primer 8: Izmena novosti (php_mysql).................................................................................26 Primer 9: Izmena novosti poboljana verzija (php_mysql).................................................29 Primer 10: Sve CRUD operacije u jednom fajlu (php_mysql)...............................................31 Primer 11: Povezivanje sa bazom podataka (php_mysqli)...................................................35 Primer 12: Unos podataka u bazu preko forme (php_mysqli)...............................................36 Primer 13: Pregled novosti (php_mysqli)..............................................................................39 Primer 14: Brisanje novosti (php_mysqli).............................................................................41 Primer 15: Izmena novosti (php_mysqli)..............................................................................44 Primer 16: Izmena novosti poboljana verzija (php_mysqli)..............................................46 Primer 17: Sve CRUD operacije u jednom fajlu (php_mysqli)...............................................48 Primer 18: Rad sa transakcijama (php_mysqli)....................................................................52 Primer 19: Pripremljeni upit (php_mysqli).............................................................................54 Primer 20: Povezivanje sa bazom podataka (php_pdo).......................................................55 Primer 21: Sve CRUD operacije u jednom fajlu (php_pdo)...................................................57 Primer 21: Sve CRUD operacije u jednom fajlu (php_pdo)

Indeks tabela

63

Tabela 1: Uporedni prikaz PHP ekstenzija za rad sa MySQL bazom.....................................6 Tabela 2: Uporedni prikaz InnoDB i MyISAM naina skladitenja..........................................9 Tabela 3: Najei SQL upiti................................................................................................15 Tabela 4: MySQL funkcije....................................................................................................16 Tabela 5: Tipovi podataka za pripremljene upite..................................................................53 Tabela 6: PDO tipovi podataka.............................................................................................56 Tabela 7: ODBC funkcije u PHP-u........................................................................................60 Tabela 7: ODBC funkcije u PHP-u

Indeks slika
Slika 1: Troslojna arhitektura web aplikacija...........................................................................3 Slika 2: Pristup dinamikim veb stranama..............................................................................4 Slika 3: PHP ekstenzije kod WAMP servera...........................................................................5 Slika 4: PhpMyAdmin.............................................................................................................7 Slika 5: Kreiranje nove baze...................................................................................................7 Slika 6: Kreiranje tabele..........................................................................................................8 Slika 7: Definisanje kolona.....................................................................................................8 Slika 8: Ubacivanje novih podataka......................................................................................10 Slika 9: Pregled sadraja tabele...........................................................................................10 Slika 10: Korienje SQL naredbi.........................................................................................11 Slika 11: Izvoz baze.............................................................................................................12 Slika 12: Uvoz baze..............................................................................................................12 Slika 13: Encoding podeavanja u programu Notepad ++....................................................13 Slika 13: Encoding podeavanja u programu Notepad ++

64

You might also like