php mysql skripta

81
SKRIPTA IZ PREDMETA INTERNET TEHNOLOGIJE Rad sa bazama podataka u PHP-u

Upload: milos-vojvodic

Post on 09-Aug-2015

137 views

Category:

Documents


5 download

DESCRIPTION

Rad sa bazama podataka u PHP-u , Preko PHP-a kao skriptnog jezika na serverskoj strani, realizuje se najveći deo poslovne logike aplikacije. Podaci vezani za aplikaciju se mogu skladištiti u običnom tekstualnom fajlu, iz kojeg se pomoću PHP mogu čitati i upisivati. Međutim, ako je u pitanju ozbiljnija aplikacija, neophodno je koristiti relacione baze podataka. Najčešće, ovo znači da će se korsititi server baze podataka koji podražava SQL (Structured Query Language) specifikaciju. SQL je standardni programski jezik za pristup i manipulaciju podacima iz relacionih baza podataka i podržan je od strane svih servera relacionih baza podataka. U relacionim bazama podaci su skladišteni preko niza tabela. Svaka tabela sadrži kolone koje opsiuju atribute podataka, a svaki red je instanca podataka.

TRANSCRIPT

Page 1: PHP MySQL Skripta

SKRIPTA IZ PREDMETA INTERNET TEHNOLOGIJE

Rad sa bazama podataka u PHP-u

Page 2: PHP MySQL Skripta

SADRŽAJ

1 UVOD...............................................................................................................................3

2 PHP i rad sa bazama podataka........................................................................................5

2.1 PhpMyAdmin.............................................................................................................6

2.1.1 Kreiranje nove baze............................................................................................7

2.1.2 Korišćenje SQL naredbi za kreiranje baze.......................................................11

2.1.3 Izvoz podataka.................................................................................................11

2.1.4 Uvoz podataka..................................................................................................12

2.2 PHP, MySQL i korišćenje naših slova.....................................................................13

2.3 Pregled najčešće korišćenih SQL upita...................................................................14

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

3.1 Konekcija na MySql server......................................................................................16

3.2 Ubacivanje podataka u bazu (naredba INSERT INTO)...........................................18

3.3 Čitanje podataka iz baze (naredba SELECT)..........................................................20

3.4 Brisanje podataka (naredba DELETE)....................................................................23

3.5 Izmena postojećih podataka (naredba UPDATE)....................................................26

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

4.1 Konekcija na MySql server......................................................................................35

4.2 Ubacivanje podataka u bazu (naredba INSERT INTO)...........................................36

4.3 Čitanje podataka iz baze (naredba SELECT)..........................................................38

4.4 Brisanje podataka (naredba DELETE)....................................................................40

4.5 Izmena postojećih podataka (naredba UPDATE)....................................................43

4.6 Rad sa transakcijama..............................................................................................51

4.7 Pripremljeni upiti......................................................................................................53

5 Ekstenzija php_pdo........................................................................................................55

6 PHP i ODBC...................................................................................................................60

Indeks primera.......................................................................................................................61

Indeks tabela..........................................................................................................................62

Indeks slika............................................................................................................................62

2

Page 3: PHP MySQL Skripta

1 UVOD

Troslojna arhitektura predstavlja tip klijent-server arhitekture u kojoj su korisnički 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 najveći deo poslovne logike aplikacije. Podaci vezani za aplikaciju se mogu skladištiti u običnom tekstualnom fajlu, iz kojeg se pomoću PHP mogu čitati i upisivati. Međutim, ako je u pitanju ozbiljnija aplikacija, neophodno je koristiti relacione baze podataka. Najčešće, ovo znači da će se korsititi server baze podataka koji podražava SQL (Structured Query Language) specifikaciju. SQL je standardni programski jezik za pristup i manipulaciju podacima iz relacionih baza podataka i podržan je od strane svih servera relacionih baza podataka. U relacionim bazama podaci su skladišteni preko niza tabela. Svaka tabela sadrži 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 način upravljanja podacima.

3

Page 4: PHP MySQL Skripta

Strane kreirane u nekom skriptnom jeziku serverske strane (npr. PHP) koje koriste neki izvor podataka (npr. podatke iz MySQL baze) nazivaju se dinamičke veb strane. One se zasnivaju na principu da se HTML kod ne stvara sve dok korisnik ne poželi da vidi veb stranicu. To dinamičko stvaranje stranica omogućuje da one budu prilagođene korisnikovim zahtevima, da zavise od prethodnih akcija korisnika, od vremena i mesta kad je pristupio lokaciji, od njegovog identiteta i specifičnih potreba.

Slika 2: Pristup dinamičkim veb stranama

Pristup dinamičkim veb stranicama teče po sledećem redosledu:

1. Veb čitač šalje HTTP zahtev veb serveru. HTTP zahtev sadrži URL sa traženom stranicom.

2. Veb server prihvata klijentski zahtev i aktivira aplikativni server. Aplikativni server je softver koji može i ne mora biti instaliran na istom računaru kao i veb server.

3. Na osnovu informacija primljenih u klijentskom zahtevu, aplikativni server prosleđuje upit ka serveru baze podataka.

4. Na osnovu dobijenog zahteva, na serveru baze podataka izvršava se odgovarajući upit. Rezultat obrade šalje se nazad do aplikativnog servera

5. Aplikativni server formira HTML stranicu u koju ugrađuje informacije dobijene iz baze podataka. HTML stranica prosleđuje se veb serveru.

6. Veb server šalje HTML stranicu do klijentskog računara.

4

Page 5: PHP MySQL Skripta

2 PHP i rad sa bazama podataka

PHP podržava API-je za pristup svim poznatim bazama podataka. Programski jezik PHP se u praksi najčešće koristi sa MySQL bazom podataka. MySQL je efikasan server za upravljanje bazama podataka. Predstavlja opensource rešenje sa odličnim performansama.

Programski jezik PHP je modularan, što znači da se sastoji iz jezgra (core) i ekstenzija, koje se po potrebi mogu uključiti. Pristup bazi podataka u programskom jeziku PHP ostvaruje se pomoću odgovarajućih PHP ekstenzija, koje su najčešće podrazumevano uključene. Bazi je moguće pristupiti na više načina. Pošto se najviše koristi MySQL server, u daljem tekstu biće razmatran pristup ovoj bazi. MySQL bazi je moguće pristupiti korišćenjem ekstenzije php_mysql, php_mysqli ili php_pdo_mysql. Takođe, PHP ima podršku za povezivanje na bilo koji sistem za upravljanje podacima pomoću ODBC drajvera.

Navedene ekstenzije je moguće uključiti ili isključiti konfigurisanjem php.ini fajla ili izborom opcije PHP PHP extensions kod WAMP servera (slika 2).

Slika 3: PHP ekstenzije kod WAMP servera

5

Page 6: PHP MySQL Skripta

Pre pojave verzije 5 PHP-a, MySql bazi moglo se jedino pristupiti korišćenjem odgovarajućih funkcija ugrađenih u php_mysql ekstenziju. Ovaj pristup se i dalje koristi, ali je danas već prevaziđen, zato što se bazi pristupalo korišćenjem proceduralnih naredbi (nije postojala objektno-orijentisana podrška), nije bilo podrške za jednostavnu promenu kodnog rasporeda baze (bez eksplicitnog poziva odgovarajućih SQL naredbi nije bio moguć korektan prikaz srpskih ili bilo kojih drugih UTF-8 karaktera), nije bilo podrške za pripremljene SQL naredbe (prepared statements) i transakcije nisu bile podržane.

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 podržavaju objektno-orijentisan pristup bazi. Dok ekstenzija php_mysqli služi isključivo za pristup MySql bazi podataka, php_pdo predstavlja univerzalnu ekstenziju za pristup bilo kom podržanom serveru baze podataka (preduslov je da postoji odgovarajući drajver za datu bazu). U tabeli 1 nalazi se uporedni prikaz navedene tri ekstenzije:

php_mysql php_mysqli php_pdo_mysqlVerzija PHP-a u kojoj se prvi put pojavljuje

3.0 5.0 5.0

Uključena u PHP verziji 5.x da da daJoš uvek se razvija ne da daPreporučena ekstenzija od strane MySQL-a

ne da (najbolja opcija) da

Podržava različite kodne rasporede

ne da da

Podržava pripremljene upite na serverskoj strani

ne da da

Podržava pripremljene upite na klijentskoj strani

ne ne da

Podržava skladištenje procedura

ne da da

Podržava izvršavanje više upita odjednom

ne da Uglavnom da

Podržava sve MySQL 4.1+ funkcionalnosti

ne da Uglavnom da

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

Postoji četiri osnovne operacije nad bazom podataka, odnosno nad perzistentnim skladištem podataka. To su operacija kreiranja podataka (create), operacija čitanja podataka (read), operacija ažuriranja podataka (update) i operacija brisanja podataka (delete). U poslovnim aplikacijama, uvek se koriste sve navedene operacije. U literaturi su one često označene nazivom crud (create, update, update, delete).

2.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 omogućava kreiranje novih baza podataka, izmenu postojećih baza, rad sa tabelama, pregled, unos, izmenu i brisanje podataka, kao i izvršavanje SQL upita. WAMP server, kao i većina kombinovanih Apache – PHP – MySQL rešenja, uključuju PhpMyAdmin aplikaciju. Ukoliko se koristi WAMP server, ovoj aplikaciji se pristupa pomoću adrese http://localhost/phpmyadmin/ ili jednostavnim klikom na ikonicu WAMP-a i izborom opcije PhpMyAdmin.

6

Page 7: PHP MySQL Skripta

Na slici 3 prikazan je interfejs aplikacije PhpMyAdmin. Sa leve strane nalazi se spisak postojećih baza podataka. Na početnoj strani je moguće kreirati novu bazu korišćenjem opcije Create New Database. Isto je moguće uraditi izborom opcije Databases. Korišćenjem opcije Privileges moguće je kreirati korisnike MySQL baze, kojima je moguće dodeliti privilegije izvršavanja određenih operacija nad bazama.

Slika 4: PhpMyAdmin

2.1.1 Kreiranje nove baze

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

Slika 5: Kreiranje nove baze

Izborom odgovarajuće opcije u padajućoj 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 korišćena i u svim narednim primerima u skripti.

Nakon kreiranja nove baze, pojaviće se ekran prikazan na slici 5.

7

Page 8: PHP MySQL Skripta

Slika 6: Kreiranje tabele

Nakon kreiranja baze, pojaviće se poruka No tables found in database. To znači 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

Pojaviće se polja za definiciju svake kolone ponaosob. Broj ovih polja zavisi od izabranog broja kolona u prethodnom koraku. Za svaku kolonu potrebno je definisati sledeće parametre:

Field – naziv kolone. Type – tip vrednosti kolone. Tipovi podataka koji se najčešće koriste su:

o INT – celobrojna vrednosto 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 znači da se može skladištiti najviše šestocifren broj, sa dva decimalna mesta. Ukoliko se unese na primer broj 123456.7890, ovaj broj će biti zaokružen na najbližu vrednost (123456.79).

o VARCHAR – kraći tekst. Pogodan je za naslove, e-mail adrese, imena i dr. Potrebno je definisati i parametar LENGTH (maksimalno 255 karaktera).

o TEXT – duži tekst. Pogodan je za sadržaj nekog članka, vest i sl.

8

Page 9: PHP MySQL Skripta

o DATETIME – polje za čuvanje vremena i datuma. Ovo polje prihvata vrednosti unete u formatu YYYY-MM-DD HH:MM.

Length/Values – maksimalna dužina polja ili skup mogućih vrednosti. Default – podrazumevana vrednost polja, ukoliko se ne definiše pri novom unosu. Collation – kodni raspored. Ukoliko se ne izabere, primenjuje se kodni raspored

baze. Attributes – atributi. Može biti binarna vrednost ili vrednost bez znaka. Obično se

ostavlja nepopunjeno. Null – selektuje se ukoliko je moguće 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 ključa, po principu automatske inkrementacije.

Comments – ovde se unose opcioni komentari vezani za dato polje.

Opcija Storage Engine odnosi se na način skladištenja podataka u datoj tabeli MySQL baze. MySQL podržava dva osnovna tipa skladištenja InnoDB i MyISAM. Njihov uporedni prikaz dat je u tabeli 2:

InnoDB MyISAMSpoljni ključevi podržava ne podržavaIntegritet podataka da neZaključavanje podataka na nivou reda na nivou tabeleIndeksiranje (pun tekst) ne daOporavak podataka bolja podrška lošija podrškaBrzina upisivanje podataka(INSERT, UPDATE)

brži sporiji

Brzina čitanja podataka(SELECT)

sporiji brži

Hardverska zahtevnost i potrošnja sistemskih resursa

zahtevniji manje zahtevan

Rad sa transakcijama da ne

Tabela 2: Uporedni prikaz InnoDB i MyISAM načina skladištenja

Primer 2 : Kreiranje tabele (PhpMyAdmin)

Baza bazanovosti treba da sadrži 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 moguće je napuniti podacima korišćenjem opcije Insert, a zatim unosom podataka (slika 7).

9

Page 10: PHP MySQL Skripta

Slika 8: Ubacivanje novih podataka

Svaka grupa polja (idnovost, naslov, tekst) predstavlja jedan red podataka u tabeli. Tabelu je moguće napuniti proizvoljnim podacima na ovaj način. Izborom opcije Browse (slika 8), moguće je videti sadržaj tabele, odnosno sve podatke koji su uneti.

Slika 9: Pregled sadržaja tabele

2.1.2 Korišćenje SQL naredbi za kreiranje baze

PhpMyAdmin podržava i kreiranje baze korišćenjem SQL naredbi. Potrebno je vratiti se na početnu stranu PhpMyAdmin-a, a zatim kliknuti na opciju SQL (slika 9). Pojaviće se forma za

10

Page 11: PHP MySQL Skripta

unos SQL naredbi. Opcija Delimiter odnosi se na znak koji razdvaja linije u upitu. Podrazumevano se koristi tačka-zarez (;).

Slika 10: Korišćenje SQL naredbi

Primer 3 : Kreiranje nove baze podataka (SQL)

Baza bazanovosti može da se kreira i pomoću 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');

2.1.3 Izvoz podataka

Da bi se sačuvala baza podataka sa svim pripadajućim tabelama i podacima, potrebno je vratiti se na početnu 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 računar. Ako ova opcija nije izabrana, prikazaće se lista SQL naredbi koje služe za kreiranje ove baze. U polje File Name Template moguće je uneti željeni naziv fajla koji će se sačuvati na računaru, kao rezultat izvoza baze. Nakon izvršenih podešavanja, treba kliknuti na taster GO, čime će se sačuvati baza na lokalnom računaru, u folderu za Download fajlova (ili na željenoj lokaciji, ako je browser tako konfigurisan).

11

Page 12: PHP MySQL Skripta

Slika 11: Izvoz baze

2.1.4 Uvoz podataka

Da bi se prethodno izvezeni podaci uvezli, neophodno je otići na početnu stranu PhpMyAdmin-a i izabrati opciju Import (slika 11). Ovde treba izabrati SQL fajl sa računara (Choose File) i kliknuti na taster GO.

Slika 12: Uvoz baze

2.2 PHP, MySQL i korišćenje naših slova

Ukoliko se ne izvrši pravilno podešavanje razvojnog okruženja i baze podataka, moguće je da se naša ćirilična ili latinična slova na stranici neće pravilno prikazati. Sve PHP fajlove je

12

Page 13: PHP MySQL Skripta

potrebno snimati u UTF-8 kodnom rasporedu. Podešavanja naravno variraju u zavisnosti od razvojnog okruženja koje se koristi. Kod podešavanja Notepad++ okruženja, trebalo bi promeniti podrazumevano podešavanje kodnog rasporeda izborom podešavanja Settings Preferences New Document / Default Directory, a zatim opcije UTF-8 without BOM u grupi opcija Encoding. BOM predstavlja skraćenicu od Byte Order Mark. To je unicode karakter koji definiše poredak bajtova dokumenta (da li je u pitanju big-endian ili little-endian). Ovaj karakter se dodaje na sam početak dokumenta, i može da predstavlja problem u radu sa PHP sesijama, upravo zbog slanja HTTP header-a koji mora uvek da bude na početku HTTP zahteva. Zbog toga je poželjno da se BOM ne koristi.

Prilikom otvaranja PHP dokumenta u razvojnom okruženju Notepad ++, uvek je moguće videti kodni raspored u kome je dokument sačuvan pomoću opcije Encoding (slika 12).

Slika 13: Encoding podešavanja u programu Notepad ++

Ukoliko je izabrana opcija Encode in UTF-8 without BOM, to znači da su podešavanja kodnog rasporeda korektna. Ukoliko je izabrana neka druga opcija, postoji mogućnost konvertovanja dokumenta u unicode izborom opcije Convert to UTF-8 without BOM, nakon čega je potrebno ponovo sačuvati dokument.

Kod HTML stranica, veoma je poželjno 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 sadržaj strane</p></body></html>

13

Page 14: PHP MySQL Skripta

Prilikom kreiranja MySQL baze, uvek treba voditi računa o parametrima collation i charset. To je detaljnije objašnjeno u prethodnom poglavlju. Trebalo bi koristiti utf8_unicode_ci raspored.

Konačno, bitno je da se utf8 kodni raspored koristi i prilikom pozivanja baze iz PHP-a. Više o tome biće objašnjeno u narednim poglavljima.

2.3 Pregled najčešće korišćenih SQL upita

SQL predstavlja struktuirani jezik za upite. Osnovna sintaksa SQL upita je praktično ista kod svih dostupnih servera bazi podataka, uz neke manje specifičnosti. U sledećoj tabeli dat je kratak prikaz SQL upita (SQL query) o kojima će kasnije biti reči:

Sintaksa upita FunkcijaCREATE DATABASE ime_baze Kreira novu SQL bazuCREATE TABLE ime_tabele (Ime_kolone1 tip podataka (velicina),Ime_kolone2 tip podataka (velicina),Ime_kolone3 tip podataka (velicina)………….)

Kreira tabelu u okviru selektovane baze podataka. Navode se imena svih kolona i tipovi podataka koje će podržavati ove kolone. Za tipove podataka u MySQL – u, pogledati reference za MySQL.

INSERT INTO ime_tabele (ime_kolone1, ime_kolone2, ime_kolone3) VALUES (“vrednost_za_kolonu1”, “vrednost_za kolonu2”, vrednost_za_kolonu3)

Ubacuje konkretne vrednosti u kreiranu tabelu u MySQL bazi podataka.

SELECT ime_kolone1,ime_kolone2, ime_kolone3, ime_koloneN FROM ime_tabele. (umesto naziva kolona može se staviti „ * “, što je džkorer znak da je sve selektovano).

Selektuje odabrane, ili sve kolone iz tabele

SELECT ime_kolone1,ime_kolone2, ime_kolone3, ime_koloneN FROM ime_tabele WHERE ime_kolone=”vrednost”

Selektuje odabrane kolone na osnovu zadatog kriterijuma.

SELECT ime_kolone1,ime_kolone2, ime_kolone3, ime_koloneN FROM ime_tabele ORDER BY ime_kolone (desc).

Selektuje odabrane kolone iz tabele i razvrstava ih u opadajućem ili rastućem redosledu na osnovu neke kolone. Ako se ne navede Desc, po default – u se podrazumeva rastući redosled.

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 ime_tabele1.kljuc1 = ime_tabele2.kljuc2

Selektuje izabrana polja iz dve tabele, koje su spojene izjednačavanjem spoljnog i primarnog ključa.

UPDATE ime_tabeleSET ime_kolone=nova_vrednostWHERE ime_kolone=stara_vrednost

Menja konkretne vrednosti iz određene tabele na osnovu zadatih kriterijuma.

DELETE FROM ime_tabeleWHERE ime_kolone=neka_vrednost

Briše konkretne vrednosti iz određene tabele na osnovu zadatih kriterijuma.

Tabela 3: Najčešći SQL upiti

14

Page 15: PHP MySQL Skripta

15

Page 16: PHP MySQL Skripta

3 Ekstenzija php_mysql

Ova ekstenzija postoji od verzije 3 programskog jezika PHP. Nalazi se i u aktuelnoj verziji 5, radi održanja kompatibilnosti sa starijim PHP aplikacijama, međutim više se ne održava. Prilikom kreiranja nove PHP aplikacije, ne preporučuje se korišćenje ove ekstenzije.

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 mreži i njima se pristupa pomoću IP-a ili domene (hosta). Uz podatak o hostu servera, potrebni su korisničko ime i lozinka da bi se uspešno povezalo na server i komuniciralo sa njim. U PHP postoji ugrađena funkcija za povezivanje sa serverom mysql_connect. Funkcija vraća 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 izvrši PHP skript.

U sledećoj tabeli su date neke od osnovnih funkcija za spajanje na MySQL server.

Naziv funkcije Sintaksa Opismysql_connect mysql_connect(ime servera:port,

korisničko ime, šifra – ukoliko postoji).Povezuje PHP skriptu sa MySQL bazom. Ako je baza zaštićena šifrom, šifra se mora uneti kao parameter.

mysql_close mysql_close (naziv promenljive kojoj je dodeljna vrednost mysql_connect funkcije)

Zatvara PHP konekciju sa bazom.

mysql_query mysql_query(“ upit koji se izvršava nad MySQL bazom“, naziv promenljive kojoj je dodeljena vrednost mysql_connection())

U okviru ove naredbe se može koristiti bilo koji upit: za kreiranje tabele, za kreiranje baze, za popunjavanje baze, ažuriranje baze, čitanje iz baze...

mysql_error mysql_error() Izveštava o mysql grešcimysql_select_db mysql_select_db(“ime_baze”) Bira MySQL bazu nad

kojom će vršiti upite

Tabela 4: MySQL funkcije

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 mogućnost promene hosting provajdera i u tom slučaju dolazi do promene parametara baze podataka. Ukoliko se parametri čuvaju samo u jednom fajlu koji se uključuje pomoću 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 slučaju da se spajanje na MySQL server navodi u svim fajlovima koji koriste podatke iz baze, neophodna je intervencija na više mesta, što nije praktično, jer može da se dogodi da veb programer previdi neku stranicu i da ta stranica neće moći da se uspešno poveže na server baze podataka.

16

Page 17: PHP MySQL Skripta

Primer 4 : Povezivanje sa bazom podataka (php_mysql)

Pomoću fajla „konekcija.php“ se vrši povezivanje sa serverom na kojem je smeštena 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 neuspešno</p>");}if (!mysql_select_db($mysql_db, $db)){die ("<p>Greška 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 tačne podaci rezultat skripte bi trebalo da bude prazna stranica.

Samo spajanje sa serverom se obavlja pomoću mysql_connect funkcije. Funkciji se prosleđuju tri argumenta. Prvi je host na kom se nalazi server. Ovde se može uneti IP ili hostname servera, ali skoro uvek se radi o alliasu localhost na IP 127.0.0.1 (barem kod većine komercijalnih hosting providera). Drugi argument je korisničko ime pomoću koje se spaja, a treći lozinka za tog korisnika. Ukoliko su svi dati podaci tačni, pa je mysql pristupačan i operacionalan funkcija će vratiti „spoj“ sa serverom. Ako je neka od informacija netačna ili se nešto desilo sa samim MySql serverom funkcija vraća false.

Još jedna vrlo bitna stvar je proveravati uspeh operacije spajanja. Naime, skoro uvek čitava poslovna logika aplikacije zahteva uspešnu konekciju na server. Sledeći 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. Pošto je spoj (rezultat mysql_connect funkcije) ubačen u varijablu $db ona je prosleđena 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 izvršava neki SQL upit na serveru). No, ukoliko se u skripti spaja na dva različita 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 situaciiji mora prosleđivati ona varijabla koja u sebi sadrži onaj spoj na kom treba izvršiti neka operaciju.

17

Page 18: PHP MySQL Skripta

3.2 Ubacivanje podataka u bazu (naredba INSERT INTO)

Baza i njoj pripadajuće tabele su u početku 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 grešci u pisanju. Naime, ukoliko se neko polje izostavi u listi njemu se automatski upisuje defaultna vrednost (koja se može postaviti pri stvaranju tabele). U ovom slučaju je pri stvaranju tabele polju idnovost data auto_increment osobina koja pri svakom insertu tom polju pridružuje po defaultu vrednost veću za 1 od poslednje upisane.

Nakon liste polja dolazi VALUES čime se naznačava 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 sačuvati 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. Najčešće 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; charset=utf-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><?phpif (isset($_POST["unos"])){//Prikupljanje podataka sa forme

if (isset($_POST['naslov'])&&isset($_POST['tekst'])){

18

Page 19: PHP MySQL Skripta

$naslov = $_POST['naslov'];$tekst = $_POST['tekst'];

//Operacije nad bazominclude "konekcija.php";$sql="INSERT INTO novosti (naslov, tekst) VALUES ('".$naslov."', '".$tekst."')";if (mysql_query($sql)){echo "<p>Novost je uspešno ubačena</p>";} else {echo "<p>Nastala je greška pri ubacivanju novosti</p>" . mysql_error();}} else {//Ako POST parametri nisu prosleđeniecho "Nisu prosleđeni 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 način 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 nešto ubaciti u bazu prvo se mora spojiti na MySql server i odabrati je, što je urađeno u prvom primeru koji je ubačen u dbsproj.php pa je ovde samo uključujen.

include "konekcija.php";

Nakon uspešnog spajanja na bazu generiše se SQL upit:

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

Sledeći korak je stvaranje stringa u kojem se nalazi sam SQL upit za unos podataka u tablicu.

if (mysql_query($sql)){echo "Novost je uspesno ubačena";} else {echo "Nastala je greška pri ubacivanju novosti<br>" . mysql_error();}

19

Page 20: PHP MySQL Skripta

Ovo je glavni deo skripte koji obavlja samu komunikaciju sa MySQL serverom, tj. izvršava SQL upit na njemu. Obavlja se pomoću mysql_query() funkcije. mysql_query() funkcija prima dva argumenta. Prvi je string podatak koji sadrži 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 ubačen u $db varijablu.

U slučaju INSERT upita mysql_query() vraća true ukoliko je upit uspešno obavljen ili false u suprotom. Iz tog razloga je moguće pomoću if-a proveriti da li je novost ubačena u bazu i u zavisnosti od toga ispusati odgovarajuću poruku korisniku.

3.3 Čitanje podataka iz baze (naredba SELECT)

Najjednostavniji primer je upit koji pribavlja sve redove iz jedne tabele.

SELECT * FROM novosti

Upit počinje 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 skraćenica 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 grešku i neće obaviti upit.

Rezultat upita nije sortiran ni po jednom polju, ali redovi su vraćeni po redosledu upisa u bazu, po idnovost polju pošto se radi o auto_increment polju koje svakom novom redu daje vrednost veću za 1 od onog prošlog.

SELECT * FROM novosti ORDER BY idnovost DESC

Da bi rezultati upita bili sortirani dodata je ORDER BY klazula u ovom slučaju na njegov kraj.

ORDER BY mora biti propraćen imenima polja po kojima se želi sortirati rezultat pa način sortiranja. U ovom slučaju se radi o polju idnovost DESC (descending) načinom, tj. u opadajućem redosledu. Suprtotno, tj. u rastućem redosledu, se može sortirati tako da se izostavi DESC ili umesto njega upiše 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><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /></head><body><?phpinclude "konekcija.php";

20

Page 21: PHP MySQL Skripta

$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><?phpwhile ($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 najopširniji. Razlog tome je prilično očigledan, jer uz obavljanje upita moraju se podaci i pribaviti tj. u ovom slučaju 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 prosleđivati mysql_query() funkciji. Može se sam upit napisati pravo u mysql_query() funkciju. Npr. ovako:

mysql_query("SELECT naslov, tekst FROM novosti ORDER BY idnovost DESC")

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

21

Page 22: PHP MySQL Skripta

Ovog puta je ubačen rezultat mysql_query funkcije u varijablu. Ovo je obavezno jedino kod izvršavanja SELECT upita dok kod izvršavanja ostalih to može biti izostavljeno.

U cilju izrade skripte koja neće ispisivati neke PHP / MySQL error-e mora se pre ispisa samog rezultata upita proveriti da li ima rezultata za prikaz, pa ukoliko nema preduzeti odgovarajuće korake da se korisnik obavesti o tome pa mu po potrebi ponuditi opcije što može učiniti u toj situaciji.

Ta provera se obavlja pomoću :

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 vraća integer broj koji je jednak ili veći od nule. Normalno, result identifier mora biti veći od nule, tj. ova funkcija će javiti error ukoliko je pri obavljanju upita nastala greška tj. mysql_query() je vratio false vrednost umesto result identifiera. Mora se voditi računa da se ova funkcija ne poziva ukoliko skripta nije prošla upit. To je u ovoj skripti osigurano die() funkcijom ukoliko je nastala greška pri izvršavanju upita. Rezultati se ispisuju u tablici radi bolje preglednosti i razumljivosti, što je vrlo bitno kod izrade dinamičkih siteova sa bazama podataka. Rezultati se naravno u zavisnosti od slučaja ne moraju prikazivati u tabeli, već mogu i da se prikažu u uređenoj ili neuređenoj 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, pošto se prikazuje samo jednom.

Nakon što su ispisani „headeri“ tabele, vraća se u PHP mode i kreće se sa ispisom podataka.

<?phpwhile ($red=mysql_fetch_array($q)){?><tr><td><?php echo $red["naslov"]?></td><td><?php echo $red ["tekst"]?></td></tr><?php}?>

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

Mysql_fetch_row() takođe vraća niz, sa tom razlikom da u njemu postoje samo numerički indeksi.

Mysql_fetch_assoc() isto vraća niz, ali u njemu se nalaze samo tekstualno indeksirana polja.

Četvrta navedena funkcija, mysql_fethc_object() umesto niza vraća objekat stvoren od polja reda.

22

Page 23: PHP MySQL Skripta

Sve gore navedene funkcije imaju zajedničko 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 zajednička stvar svim pomenutim funkcijama je da kao svoj argument dobijaju result identifier koji vraća 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.

3.4 Brisanje podataka (naredba DELETE)

SQL naredba za brisanje podataka je :

DELETE FROM tabela

U prevodu gornja naredba znači „Obriši sve iz tabele imena tabela“, ali ovo je očigledno situacija koja će se retko događati u nekim realnim skriptama, već se obično 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 služi za naznačavanje da nakon njega slede uslovi pomoću kojih se ograničava skup podataka nad kojima će se obaviti neka operacija.

DELETE FROM novosti WHERE naslov = ‘Naslov1’

U prevodu, zadato je MySql-u da obriše sve naslove koji imaju vrednost naslov1. Unutar WHERE klazule je moguće kombinovati više uslova koji ograničavaju skup podataka nad kojima se obavlja operacija kombinovanjem logičkim operatorima. WHERE može shvatiti kao if u PHP-u koji se obavlja nad svakim redom tabele.

Takođe, pomoću DELETE naredbe nije moguće obrisati pojedinu vrednost unutar nekog polja tabele. Nije moguće obrisati naslov novosti čiji je idnovst jednak 1. Za to se koristi UPDATE naredba koja će biti objašnjena u sledećem poglavlju.

Brisanje se najčešće implementira u kombinaciji sa prikazom sadržaja baze. Prethodni primer će biti proširen tako da pored svake novosti postoji dinamički generisan link, koji će tu novost da izbriše. Dinamički generisani linkovi funkcionišu tako što se pored naziva stranice na koju vodi link prosleđuje i GET parametar, koji je različit na osnovu stavke kojoj pripada. Kada se vrši linkovanje, ako link počinje upitnikom (?), to znači da će voditi na tekuću php stranicu, a da će njoj proslediti date GET parametre.

Primer 7 : Brisanje novosti (php_mysql)

<!DOCTYPE html>

23

Page 24: PHP MySQL Skripta

<html><head><title>Pregled novosti</title><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /></head><body><?phpinclude "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 uspešno!</p>";}break;default:echo "<p>Nepostojeća 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><?phpwhile ($red=mysql_fetch_array($q)){?><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}

24

Page 25: PHP MySQL Skripta

?></table><?php}mysql_close($db);?></body></html>

Prethodnom primeru, gde je bio objašnjen prikaz podataka iz baze, dodata je funkcionalnost brisanja. SQL upit za listanje podataka morao je biti malo izmenjen, pošto će biti neophodno korišćenje atributa idnovost, za generisanje dinamičkog linka za brisanje novosti. Ispod uključivanja fajla konekcija.php, proverava se da li je prosleđen GET parametar akcija i idnovost. Ukoliko jesu prosleđeni, radi jednostavnost, definišu se promenljive akcija i id na osnovu prosleđenih GET parametara, pa se zatim proverava vrednost parametra akcija pomoću switch-case bloka naredbi. Ovde je moguće koristiti i if..else, međutim switch-case je bolje rešenje, zato što može da postoji više različitih akcija.

Ukoliko je vrednost GET parametra akcija brisanje, kreće 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 uspešno!</p>";}

Izvršavanje upita je vrlo slično kao kod INSERT upita. Dovoljno je obaviti upit pomoću mysql_query() funkcije. Čak nije obavezno ubaciti njen rezultat u neku varijablu pošto ne postoji potreba za njenim korišćenjem kasnije u skripti.

Očigledno, ukoliko mysql_query() vrati true može se pretpostaviti da je novost obrisana a ukoliko vrati false znači da je nastala neka greška koju će mysql_error() opisati.

Da bi proverili da li je novost stvarno obrisana, može se koristiti još jedna mysql funkcija koja se nalazi u PHP-u. Radi se o mysql_affected_rows() funkciji. Funkcija vraća broj redova koji su bili zahvaćeni poslednjom operacijom. Može se koristiti samo nakon DELETE, UPDATE i INSERT upita, tj. upita koji vrše izmene nad podacima tabela.

$sql="DELETE FROM novosti WHERE idnovost=" . $_GET["idnovost"];if (mysql_query($sql)){if (mysql_affected_rows() > 0 ){echo "Novost je uspešno obrisana";} else {echo "Nije obrisana ni jedna novost!";}} else {echo "Nastala je greška pri brisanju novosti<br>" . mysql_error();}

Deo koda:

25

Page 26: PHP MySQL Skripta

<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 slučaju to je isti onaj fajl koji se izvršava. Dodatni parameter je idnovost, koji dobija vrednost u zavisnosti od toga koji red je izabran.

3.5 Izmena postojećih 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 počinje navođenjem 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 pridruženim novim vrednostima. Nakon izvršavanja gornjeg primera bi u svim redovima tabele naslov bio promenjen u „Novi naslov“.

Ukoliko je potrebno izmeniti više polja istovremeno, to bi bilo učinjeno ovakvim upitom:

UPDATE novosti SET naslov="Novi naslov", tekst="abcdefghijk"

Znači, za izvođenje izmena vrednosti u više polja potrebno je dva naziva polja sa pridruženim vrednostima odvojiti zarezom. Normalno, izmena vrednosti svim redovima neke tabele je vrlo retka pojava u realnim skriptama. Iz tog razloga je moguće pomoću WHERE klazule ograničiti skup podataka nad kojima se vršiizmena. U konkretnom primeru bi to izgledalo od prilike ovako :

UPDATE novosti SET naslov="Novi naslov", tekst="abcdefghijk" WHERE idnovost=1

Ovim upitom je izmenjen naslov i tekst novosti koja ima ID jednak jedan.

Naredni primer se takođe nadograđuje 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 pomoću generisanog dinamičkog linka i akcija izmena, koja vrši konkretnu UPDATE operaciju nad bazom (poziva se klikom na taster submit na formi prikazanoj pomoću akcije izmena_forma). Dinamički link za izmenu se generiše na istovetan način kao i dinamički link za brisanje, uveden u prethodnom primeru. Naravno, u okviru jednog PHP fajla moguće je kombinovati GET i POST parametre. Pomoću GET parametra će se uvek prosleđivati vrednost akcije i vrednost parametra idnovost, a pomoću POST parametara prosleđivaće 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=utf-8" />

26

Page 27: PHP MySQL Skripta

</head><body><?phpinclude "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 uspešno!</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><?phpbreak;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 uspešno izmenjena.</p>";} else {echo "<p>Novost nije izmenjena.</p>";}} else {echo "<p>Nastala je greška pri izmeni novosti</p>" . mysql_error();}} else {echo "<p>Nisu prosleđeni parametri za izmenu";}break;default:echo "<p>Nepostojeća 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();

27

Page 28: PHP MySQL Skripta

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><?phpwhile ($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>

Kao i u dosadašnjim primerima, na samom početku skripte je uključen konekcija.php.

Dodata je nova akcija izmena_forma. Ova akcija takođe prosleđuje id novosti preko GET parametra i ukoliko je pozvana, prikazuje formu za izmenu. Generisan je dinamički link ka ovoj akciji, na sličan način kao dinamički link za brisanje.

Klikom na taster submit, poziva se akcija izmena i prosleđuje se parametar idnovost, koji je takođe prikupljen pomoću GET metode. Ova akcija proverava da li su prosleđeni POST parametri sa novim vrednostima, prikupljeni iz forme. Ukoliko jesu, izvršava se upit koji vrši izmenu u bazi:

$upit="UPDATE novosti SET naslov='". $naslov ."', tekst='" . $tekst . "' WHERE idnovost=". $id;

28

Page 29: PHP MySQL Skripta

if (mysql_query($upit)){if (mysql_affected_rows() > 0 ){echo "<p>Novost je uspešno izmenjena.</p>";} else {echo "<p>Novost nije izmenjena.</p>";}} else {echo "<p>Nastala je greška pri izmeni novosti</p>" . mysql_error();}

U praksi se najčešće menja samo jedno polje, a retko kada sva polja. Navedeni primer ne prosleđuje postojeće vrednosti polja u formu za izmenu, čime se povećava mogućnost slučajne izmene nekog polja, odnosno mogućnost da se izbriše sadržaj nekog polja. Uvek bi trebalo proslediti vrednost tekućeg polja iz baze u formu za izmenu polja. Sledeći primer pokazuje kako je to moguće uraditi:

Primer 9 : Izmena novosti – poboljšana verzija (php_mysql)

<!DOCTYPE html><html><head><title>Pregled novosti</title><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /></head><body><?phpinclude "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 uspešno!</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>Nepostojeća novost.</p>";} else {$novost = mysql_fetch_array($q);$naslov = $novost ['naslov'];

29

Page 30: PHP MySQL Skripta

$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 uspešno izmenjena.</p>";} else {echo "<p>Novost nije izmenjena.</p>";}} else {echo "<p>Nastala je greška pri izmeni novosti</p>" . mysql_error();}} else {echo "<p>Nisu prosleđeni parametri za izmenu";}break;default:echo "<p>Nepostojeća 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>

30

Page 31: PHP MySQL Skripta

<td><b>Tekst</b></td><td><b>Akcija</b></td></tr><?phpwhile ($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 izvršavanje SELECT upita u akciji izmena_forma. Proverava se da li postoji tačno jedna vrednost novosti sa datim id-om i ukoliko postoji, prikazuju se podaci u bazi. Ovde nije neophodno korišćenje while petlje, pošto je u pitanju samo jedna vrednost.

Konačno, 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. Pošto ova akciji nisu potrebni dodatni parametri, kao što je idnovost, potrebno ju je definisati van swich-case bloka (pošto se on izvršava nakon provere GET parametara akcija i idnovost). U okviru akcije, mogu se definisati i forma i samo izvršavanje 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; charset=utf-8" /></head>

31

Page 32: PHP MySQL Skripta

<body><?phpinclude "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><?phpif (isset($_POST["unos"])){//Prikupljanje podataka sa forme

if (isset($_POST['naslov'])&&isset($_POST['tekst'])){$naslov = $_POST['naslov'];$tekst = $_POST['tekst'];

//Operacije nad bazominclude "konekcija.php";$sql="INSERT INTO novosti (naslov, tekst) VALUES ('".$naslov."', '".$tekst."')";if (mysql_query($sql)){echo "<p>Novost je uspešno ubačena.</p>";} else {echo "<p>Nastala je greška pri ubacivanju novosti</p>" . mysql_error();}} else {//Ako POST parametri nisu prosleđeniecho "Nisu prosleđeni parametri!";}}}}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 uspešno!</p>";}break;case "izmena_forma":$upit="SELECT idnovost, naslov, tekst FROM novosti WHERE idnovost=".$id;

32

Page 33: PHP MySQL Skripta

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>Nepostojeća 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 uspešno izmenjena.</p>";} else {echo "<p>Novost nije izmenjena.</p>";}} else {echo "<p>Nastala je greška pri izmeni novosti</p>" . mysql_error();}} else {echo "<p>Nisu prosleđeni parametri za izmenu";}break;default:echo "<p>Nepostojeća 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)

33

Page 34: PHP MySQL Skripta

{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><?phpwhile ($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);?><p><a href="?akcija=unos">Unos novosti</a></p></body></html>

34

Page 35: PHP MySQL Skripta

4 Ekstenzija php_mysqli

Ova ekstenzija postoji od verzije 5 programskog jezika PHP. Danas se preporučuje njeno korišćenje, zato što ima više funkcionalnosti od php_mysql ekstenzije i nešto bolje performanse. Takođe, podržava objektno-orijentisano programiranje.

4.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 mreži i njima se pristupa pomoću IP-a ili domene (hosta). Uz podatak o hostu servera, potrebni su korisničko ime i lozinka da bi se uspešno povezalo na server i komuniciralo sa njim. Ekstenzija php_mysqli se povezuje na MySQL server i vrši odabir baze kreiranjem novog objekta klase mysqli. Parametri konstruktora su :

IP adresa ili hostname MySQL servera MySQL korisničko ime MySQL lozinka MySQL baza koja se odabira

Sintaksa povezivanja na MySQL bazu korišćenjem mysqli ekstenzije je sledeća:

$mysqli = new mysqli($mysql_server, $mysql_user, $mysql_pass, $mysql_db);

Nakon kreiranja mysqli objekta, treba proveriti da li je konekcija uspešna. Atribut connect_errno() vraća šifru greške ukoliko je nastupila. Zatim bi trebalo odabrati charset u kome se nalaze podaci. To se radi korišćenjem naredbe set_charset("set_karaktera"). Na primer, za izbor UTF-8 charset-a, treba izvršiti 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 mogućnost promene hosting provajdera i u tom slučaju dolazi do promene parametara baze podataka. Ukoliko se parametri čuvaju samo u jednom fajlu koji se uključuje pomoću 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 slučaju da se spajanje na MySQL server navodi u svim fajlovima koji koriste podatke iz baze, neophodna je intervencija na više mesta, što nije praktično, jer može da se dogodi da veb programer previdi neku stranicu i da ta stranica neće moći da se uspešno poveže na server baze podataka.

Primer 11 : Povezivanje sa bazom podataka (php_mysqli)

Pomoću fajla „konekcija.php“ se vrši povezivanje sa serverom na kojem je smeštena baza.

<?php

35

Page 36: PHP MySQL Skripta

$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 neuspešna: %s\n", $mysqli->connect_error); exit();}$mysqli->set_charset("utf8");?>

Ukoliko su MySqli funkcijama dati tačne podaci rezultat skripte bi trebalo da bude prazna stranica. MySqli konekcija se zatvara korišćenjem funkcije close().

4.2 Ubacivanje podataka u bazu (naredba INSERT INTO)

Baza i njoj pripadajuće tabele su u početku 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 grešci u pisanju. Naime, ukoliko se neko polje izostavi u listi njemu se automatski upisuje defaultna vrednost (koja se može postaviti pri stvaranju tabele). U ovom slučaju je pri stvaranju tabele polju idnovost data auto_increment osobina koja pri svakom insertu tom polju pridružuje po defaultu vrednost veću za 1 od poslednje upisane.

Nakon liste polja dolazi VALUES čime se naznačava 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 sačuvati 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. Najčešće se podaci prikupljaju od korisnika. U tekstu sledi primer ubacivanja podataka prikupljenih preko forme.

Primer 12 : Unos podataka u bazu preko forme (php_mysqli)

<!DOCTYPE html>

36

Page 37: PHP MySQL Skripta

<html><head><title>Unos novosti</title><meta http-equiv="Content-Type" content="text/html; charset=utf-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><?phpif (isset($_POST["unos"])){//Prikupljanje podataka sa forme

if (isset($_POST['naslov'])&&isset($_POST['tekst'])){$naslov = $_POST['naslov'];$tekst = $_POST['tekst'];

//Operacije nad bazominclude "konekcija.php";$sql="INSERT INTO novosti (naslov, tekst) VALUES ('".$naslov."', '".$tekst."')";if ($mysqli->query($sql)){echo "<p>Novost je uspešno ubačena</p>";} else {echo "<p>Nastala je greška pri ubacivanju novosti</p>" . $mysqli->error;}} else {//Ako POST parametri nisu prosleđeniecho "Nisu prosleđeni parametri!";}$mysqli->close();}?></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 način 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.

37

Page 38: PHP MySQL Skripta

Drugi korak ubacuje podatke iz forme u bazu. Da bi se moglo nešto ubaciti u bazu prvo se mora spojiti na MySql server i odabrati je, što je urađeno u prvom primeru koji je ubačen u dbsproj.php pa je ovde samo uključujen.

include "konekcija.php";

Nakon uspešnog spajanja na bazu generiše se SQL upit:

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

Sledeći 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 uspešno ubačena</p>";} else {echo "<p>Nastala je greška pri ubacivanju novosti</p>" . $mysqli->error;}

Ovo je glavni deo skripte koji obavlja samu komunikaciju sa MySQL serverom, tj. izvršava SQL upit na njemu. Obavlja se pomoću 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, pomoću naredbe $mysqli->close().

Često je neophodno da aplikacioni programer zna koji ID je dodeljen unetom zapisu, u slučaju da se koristi automatsko inkrementiranje kod primarnog ključa tabele u koju se ubacuje novi zapis. U tu svrhu se koristi $mysqli->insert_id atribut, koji vraća generisani ID primarnog ključa nakon izvršenja INSERT upita.

4.3 Čitanje podataka iz baze (naredba SELECT)

Najjednostavniji primer je upit koji pribavlja sve redove iz jedne tabele.

SELECT * FROM novosti

Upit počinje 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 skraćenica 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 grešku i neće obaviti upit.

Rezultat upita nije sortiran ni po jednom polju, ali redovi su vraćeni po redosledu upisa u bazu, po idnovost polju pošto se radi o auto_increment polju koje svakom novom redu daje vrednost veću za 1 od onog prošlog.

SELECT * FROM novosti ORDER BY idnovost DESC

38

Page 39: PHP MySQL Skripta

Da bi rezultati upita bili sortirani dodata je ORDER BY klazula u ovom slučaju na njegov kraj.

ORDER BY mora biti propraćen imenima polja po kojima se želi sortirati rezultat pa način sortiranja. U ovom slučaju se radi o polju idnovost DESC (descending) načinom, tj. u opadajućem redosledu. Suprtotno, tj. u rastućem redosledu, se može sortirati tako da se izostavi DESC ili umesto njega upiše 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=utf-8" /></head><body><?phpinclude "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><?phpwhile ($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>

39

Page 40: PHP MySQL Skripta

SELECT upiti su najopširniji. Razlog tome je prilično očigledan, jer uz obavljanje upita moraju se podaci i pribaviti tj. u ovom slučaju 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 sačuvan u promenljivoj $mysqli (naziv ove promenljive naravno može da bude proizvoljan). Pomoću include funkcije, omogućava se pristup ovoj promenljivoj dalje u php skripti. Zatim se izvršava sql upit, pozivanjem funkcije query(), sa prosleđenim SQL upitom, kao argumentom funkcije (slično kao u prethodnom primeru). Ukoliko je upit uspešno kreiran, proverava se broj redova, pomoću atributa num_rows. Ukoliko ovaj broj nije nula, izvršiće se while petlja, koja će imati onoliko iteracija koliko ima redova u tabeli izvršenog SELECT upita. Ovde je najbolje koristiti funkciju fetch_object() koja vraća jedan red tabele u formi objekta. Vrednostima svake kolone se pristupa pomoću atributa objekta.

Osim funkcije fetch_object(), koja vraća red tabele kao objekat, koriste se i sledeće funkcije:

fetch_array() vraća red, tj. niz koji se sastojih od svih polja rezultata s tim da je svako polje indeksirano brojem i svojim imenom.

fetch_row() takođe vraća niz, sa tom razlikom da u njemu postoje samo numerički indeksi.

fetch_assoc() isto vraća niz, ali u njemu se nalaze samo tekstualno indeksirana polja.

4.4 Brisanje podataka (naredba DELETE)

SQL naredba za brisanje podataka je :

DELETE FROM tabela

U prevodu gornja naredba znači „Obriši sve iz tabele imena tabela“, ali ovo je očigledno situacija koja će se retko događati u nekim realnim skriptama, već se obično 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 služi za naznačavanje da nakon njega slede uslovi pomoću kojih se ograničava skup podataka nad kojima će se obaviti neka operacija.

DELETE FROM novosti WHERE naslov = ‘Naslov1’

U prevodu, zadato je MySql-u da obriše sve naslove koji imaju vrednost naslov1. Unutar WHERE klazule je moguće kombinovati više uslova koji ograničavaju skup podataka nad kojima se obavlja operacija kombinovanjem logičkim operatorima. WHERE može shvatiti kao if u PHP-u koji se obavlja nad svakim redom tabele.

40

Page 41: PHP MySQL Skripta

Takođe, pomoću DELETE naredbe nije moguće obrisati pojedinu vrednost unutar nekog polja tabele. Nije moguće obrisati naslov novosti čiji je idnovst jednak 1. Za to se koristi UPDATE naredba koja će biti objašnjena u sledećem poglavlju.

Brisanje se najčešće implementira u kombinaciji sa prikazom sadržaja baze. Prethodni primer će biti proširen tako da pored svake novosti postoji dinamički generisan link, koji će tu novost da izbriše. Dinamički generisani linkovi funkcionišu tako što se pored naziva stranice na koju vodi link prosleđuje i GET parametar, koji je različit na osnovu stavke kojoj pripada. Kada se vrši linkovanje, ako link počinje upitnikom (?), to znači da će voditi na tekuću 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=utf-8" /></head><body><?phpinclude "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 uspešno!</p>";}break;default:echo "<p>Nepostojeća 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><td><b>Naslov</b></td>

41

Page 42: PHP MySQL Skripta

<td><b>Tekst</b></td><td><b>Akcija</b></td></tr><?phpwhile ($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 objašnjen prikaz podataka iz baze, dodata je funkcionalnost brisanja. SQL upit za listanje podataka morao je biti malo izmenjen, pošto će biti neophodno korišćenje atributa idnovost, za generisanje dinamičkog linka za brisanje novosti. Ispod uključivanja fajla konekcija.php, proverava se da li je prosleđen GET parametar akcija i idnovost. Ukoliko jesu prosleđeni, radi jednostavnost, definišu se promenljive akcija i id na osnovu prosleđenih GET parametara, pa se zatim proverava vrednost parametra akcija pomoću switch-case bloka naredbi. Ovde je moguće koristiti i if..else, međutim switch-case je bolje rešenje, zato što može da postoji više različitih akcija.

Ukoliko je vrednost GET parametra akcija brisanje, kreće 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 uspešno!</p>";}

Izvršavanje upita je vrlo slično kao kod INSERT upita. Dovoljno je obaviti upit pomoću mysql_query() funkcije. Čak nije obavezno ubaciti njen rezultat u neku varijablu pošto ne postoji potreba za njenim korišćenjem kasnije u skripti.

Da bi proverili da li je novost stvarno obrisana, može se koristiti mysqli atribut affected_rows. Atribut vraća broj redova koji su bili zahvaćeni poslednjom operacijom. Može se koristiti samo nakon DELETE, UPDATE i INSERT upita, tj. upita koji vrše 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)){echo "Nastala je greska pri izvodenju upita<br/>" . mysql_query();

42

Page 43: PHP MySQL Skripta

die();} else {if ($mysqli->affected_rows > 0 ){echo "<p>Brisanje zapisa je uspešno!</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 slučaju to je isti onaj fajl koji se izvršava. Dodatni parameter je idnovost, koji dobija vrednost u zavisnosti od toga koji red je izabran.

4.5 Izmena postojećih 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 počinje navođenjem 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 pridruženim novim vrednostima. Nakon izvršavanja gornjeg primera bi u svim redovima tabele naslov bio promenjen u „Novi naslov“.

Ukoliko je potrebno izmeniti više polja istovremeno, to bi bilo učinjeno ovakvim upitom:

UPDATE novosti SET naslov="Novi naslov", tekst="abcdefghijk"

Znači, za izvođenje izmena vrednosti u više polja potrebno je dva naziva polja sa pridruženim vrednostima odvojiti zarezom. Normalno, izmena vrednosti svim redovima neke tabele je vrlo retka pojava u realnim skriptama. Iz tog razloga je moguće pomoću WHERE klazule ograničiti skup podataka nad kojima se vršiizmena. U konkretnom primeru bi to izgledalo od prilike ovako :

UPDATE novosti SET naslov="Novi naslov", tekst="abcdefghijk" WHERE idnovost=1

Ovim upitom je izmenjen naslov i tekst novosti koja ima ID jednak jedan.

Naredni primer se takođe nadograđuje 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 pomoću generisanog dinamičkog linka i akcija izmena, koja vrši konkretnu UPDATE operaciju nad bazom (poziva se klikom na taster submit na formi prikazanoj pomoću akcije izmena_forma). Dinamički link za izmenu se generiše na istovetan način kao i dinamički link za brisanje, uveden u prethodnom primeru. Naravno, u okviru jednog PHP fajla moguće je kombinovati GET i POST parametre. Pomoću GET parametra će se uvek prosleđivati vrednost akcije i vrednost parametra idnovost, a pomoću POST parametara prosleđivaće se nove vrednosti nakon izmene.

43

Page 44: PHP MySQL Skripta

Primer 15 : Izmena novosti (php_mysqli)

<!DOCTYPE html><html><head><title>Pregled novosti</title><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /></head><body><?phpinclude "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 uspešno!</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><?phpbreak;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 uspešno izmenjena.</p>";} else {echo "<p>Novost nije izmenjena.</p>";}} else {echo "<p>Nastala je greška pri izmeni novosti</p>" . mysql_error();}} else {echo "<p>Nisu prosleđeni parametri za izmenu";

44

Page 45: PHP MySQL Skripta

}break;default:echo "<p>Nepostojeća 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><?phpwhile ($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 dosadašnjim primerima, na samom početku skripte je uključen konekcija.php.

Dodata je nova akcija izmena_forma. Ova akcija takođe prosleđuje id novosti preko GET parametra i ukoliko je pozvana, prikazuje formu za izmenu. Generisan je dinamički link ka ovoj akciji, na sličan način kao dinamički link za brisanje.

45

Page 46: PHP MySQL Skripta

Klikom na taster submit, poziva se akcija izmena i prosleđuje se parametar idnovost, koji je takođe prikupljen pomoću GET metode. Ova akcija proverava da li su prosleđeni POST parametri sa novim vrednostima, prikupljeni iz forme. Ukoliko jesu, izvršava se upit koji vrši 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 uspešno izmenjena.</p>";} else {echo "<p>Novost nije izmenjena.</p>";}} else {echo "<p>Nastala je greška pri izmeni novosti</p>" . mysql_error();}

U praksi se najčešće menja samo jedno polje, a retko kada sva polja. Navedeni primer ne prosleđuje postojeće vrednosti polja u formu za izmenu, čime se povećava mogućnost slučajne izmene nekog polja, odnosno mogućnost da se izbriše sadržaj nekog polja. Uvek bi trebalo proslediti vrednost tekućeg polja iz baze u formu za izmenu polja. Sledeći primer pokazuje kako je to moguće uraditi:

Primer 16 : Izmena novosti – poboljšana verzija (php_mysqli)

<!DOCTYPE html><html><head><title>Pregled novosti</title><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /></head><body><?phpinclude "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 uspešno!</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();

46

Page 47: PHP MySQL Skripta

} else {if ($q->num_rows!=1){echo "<p>Nepostojeća 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 uspešno izmenjena.</p>";} else {echo "<p>Novost nije izmenjena.</p>";}} else {echo "<p>Nastala je greška pri izmeni novosti</p>" . mysql_error();}} else {echo "<p>Nisu prosleđeni parametri za izmenu";}break;default:echo "<p>Nepostojeća 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>

47

Page 48: PHP MySQL Skripta

<hr/><table><tr><td><b>Naslov</b></td><td><b>Tekst</b></td><td><b>Akcija</b></td></tr><?phpwhile ($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 izvršavanje SELECT upita u akciji izmena_forma. Proverava se da li postoji tačno jedna vrednost novosti sa datim id-om i ukoliko postoji, prikazuju se podaci u bazi. Ovde nije neophodno korišćenje while petlje, pošto je u pitanju samo jedna vrednost.

Konačno, 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. Pošto ova akciji nisu potrebni dodatni parametri, kao što je idnovost, potrebno ju je definisati van swich-case bloka (pošto se on izvršava nakon provere GET parametara akcija i idnovost). U okviru akcije, mogu se definisati i forma i samo izvršavanje 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 17 : Sve CRUD operacije u jednom fajlu (php_mysqli)

<!DOCTYPE html><html><head><title>Pregled novosti</title>

48

Page 49: PHP MySQL Skripta

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /></head><body><?phpinclude "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><?phpif (isset($_POST["unos"])){//Prikupljanje podataka sa forme

if (isset($_POST['naslov'])&&isset($_POST['tekst'])){$naslov = $_POST['naslov'];$tekst = $_POST['tekst'];

//Operacije nad bazominclude "konekcija.php";$sql="INSERT INTO novosti (naslov, tekst) VALUES ('".$naslov."', '".$tekst."')";if ($mysqli->query($sql)){echo "<p>Novost je uspešno ubačena.</p>";} else {echo "<p>Nastala je greška pri ubacivanju novosti</p>" . mysql_error();}} else {//Ako POST parametri nisu prosleđeniecho "Nisu prosleđeni parametri!";}}}}

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 uspešno!</p>";}break;case "izmena_forma":

49

Page 50: PHP MySQL Skripta

$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>Nepostojeća 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 uspešno izmenjena.</p>";} else {echo "<p>Novost nije izmenjena.</p>";}} else {echo "<p>Nastala je greška pri izmeni novosti</p>" . mysql_error();}} else {echo "<p>Nisu prosleđeni parametri za izmenu";}break;default:echo "<p>Nepostojeća 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();}

50

Page 51: PHP MySQL Skripta

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><?phpwhile ($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>

4.6 Rad sa transakcijama

Transakcija je jedno izvršenje neke „logičke jedinice posla“, jedno izvršenje neke logičke celine jednog programa ili jedno izvršenje celog programa. Svaka transakcija ima osobine atomnosti, konzistentnosti, izolacije i trajnosti.1

MySQL sistem upravljanja podacima podržava rad sa transakcijama, ali samo pri korišćenju InnoDB storage engine-a. Transakcija može predstavljati blok SQL upita, koji moraju da se izvrše sukcesivno. Prilikom izvršavanja transakcije, baza podataka se zaključa i niko ne može da vrši operacije nad njom dok se transakcija ne izvrši. Srećom, vreme izvršavanja transakcije meri se u milisekundama.

1 Branislav Lazarević, Zoran Marjanović, Nenad Aničić, Slađan Babarogić – Baze podataka, FON, Beograd, 2006.

51

Page 52: PHP MySQL Skripta

Za izvršavanje transakcije, koriste se instrukcije COMMIT i ROLLBACK. Instrukcija COMMIT služi za izvršavanje transakcije, a ROLLBACK za vraćanje baze na prethodno stanje ukoliko se transakcija ne izvrši uspešno.

Pri radu sa transakcijama, poželjno je prvo isključiti opciju AUTOCOMMIT. Ona služi za automatsko izvršavanja transakcija i eventualno vraćanje na prethodno stanje u slučaju greške. Na primer, jedna transakcija može da predstavlja ubacivanje više 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/><?phpinclude "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 ('Treća vest', 'Tekst treće vesti')");if ($q1 && $q2 && $q3){$mysqli->commit();echo "<p>Novosti su uspešno ubačene!</p>";} else {$mysqli->rollback();echo "<p>Novosti nisu ubačene!</p>";}$mysqli->close();?></body></html>

Nakon isključivanja AUTOCOMMIT opcije, treba izvršiti sve upite nad bazom koji čine transakciju. Svaki upit treba sačuvati kao promenljivu. Ukoliko je upit uspešno izvršen, tada je vrednost promenljive TRUE. Nakon izvršavanja upita, potrebno je proveriti da li su svi upiti koji čine transakciju uspešno izvršeni, odnosno da li je vrednost promenljivih koje su sačuvale vrednost upita TRUE. Ukoliko je to slučaj, potrebno je potvrditi uspešno izvršenje transakcije funkcijom commit(). Ako je bar jedan upit nekorektan, tada treba vratiti bazu na početno stanje korišćenjem funkcije rollback().

U datom primeru, svi upiti su korektni, pa će se izvršiti transakcija. Ukoliko se izvrši izmena bilo kog upita i ubaci neka tipografska greška (npr. INSET umesto INSERT), izvršiće se rollback() i promene nijednog upita neće biti sačuvane.

52

Page 53: PHP MySQL Skripta

4.7 Pripremljeni upiti

Pripremljene naredbe (prepared statements) programerima olakšavaju 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 povežu sa nekim PHP promenljivama, posle čega se konačno izvršava upit. Pripremljene naredbe su vrsta šablona (templejta) koji služi za jednostavniji rad sa upitima. Njihova primena je posebno značajna kod manipulacije više 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 može primetiti da u delu upita VALUES stoje upitnici, umesto pravih vrednosti koje bi trebalo ubaciti u bazu.

Zatim je potrebno izvršiti povezivanje parametara i upitnika. To se radi pomoću funkcije bind_param(). Ova funkcija prima najmanje dva ulazna argumenta. Prvi argument je string koji sadrži slova koja predstavljaju tip vrednosti parametra. Ukoliko ima jedan upitnik u pripremljenom upitu, trebalo bi da ovde stoji jedno slovo, a u slučaju da na primer ima pet upitnika, ovde treba da stoji pet slova bez razmaka. Mogući tipovi podataka (odnosno slova) prikazani su u tabeli:

Slovo Tip podatkai Integer (celobrojna vrednost)d Double (decimalna vrednost)s Stringb 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 (treći argument funkcije) drugom upitniku itd.

Sledeći blok naredbi:

$naslov = "Neki naslov";$tekst = "Tekst novosti";$upit->bind_param("ss", $naslov, $tekst);

definiše promenljivu $naslov i $tekst, a zatim ih povezuje sa pripremljenim upitom, korišćenjem funkcije bind_param(). Prvi argument "ss" označava 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);

53

Page 54: PHP MySQL Skripta

U sledećem primeru, obrađen je jednostavan slučaj korišćenja 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/><?phpinclude "konekcija.php";//Pripremanje upita$upit_string = "INSERT INTO novosti (naslov, tekst) VALUES (?, ?)";$upit = $mysqli->prepare ($upit_string);//Definisanje promenljivih čije vrednosti će biti ubačene u bazu$naslov = "Neki naslov";$tekst = "Tekst novosti";//Povezivanje parametara sa promenljivama$upit->bind_param("ss", $naslov, $tekst);$upit->execute();$mysqli->close();?></body></html>

54

Page 55: PHP MySQL Skripta

5 Ekstenzija php_pdo

PHP Data Objects predstavlja PHP ekstenziju koja definiše konzistentan interfejs za pristup bazama podataka. PDO zapravo predstavlja svojevrsnog database brokera za programski jezik PHP. Njime je omogućen rad sa više različitih sistema za upravljanja podacima. Podržani su MySQL, Microsoft SQL Server, ODBC, SQLite i dr.

Drugim rečima, PDO obezbeđuje sloj apstrakcije pristupu podataka, što znači da se kod svih sistema za upravljanje podacima koriste iste funkcije za pokretanje upita i uzimanje podataka. PDO ne obezbeđuje apstrakciju samih podataka, što znači da ne apstrahuje same upite. Napredniji SQL upiti mogu malo da variraju kod različitih database servera, ali su osnovni SQL upiti uvek isti.

Ekstenzija php_pdo radi sa drajverima specijalno pisanim za ovu ekstenziju. To znači da npr. MySQL koristi jedan drajver, SQLite drugi drajver i sl. Za rad sa PDO treba uključiti odgovarajuću ekstenziju. Npr. za PDO sa podrškom za MySQL, treba uključiti php_pdo_mysql, za rad sa SQLite bazom php_pdo_sqlite i dr.

Za konekciju sa bazom pomoću PDO-a, potrebno je kreirati novi objekat klase PDO. Prvi parametar konstruktora je uvek konekcioni string, drugi parametar je korisničko ime za pristup bazi, treći parametar je lozinka za pristup bazi, a četvrti parametar je niz sa dodatnim parametrima podešavanja konekcije. Prvi parametar je uvek obavezan, a svi ostali su opcioni.

Konekcioni string (DSN, data source name) sadrži informacije neophodne za pristup bazi. On je specifičan za sam database server i razlikuje se za MySQL, MSSQL, SQLite i dr. Uvek sadrži tip servera baze podataka, IP adresu ili hostname database servera i naziv baze koja treba da se izabere. Na primer, konekcioni string za MySQL biće:

$db = new PDO('mysql:host=localhost;dbname=bazanovosti', 'root', '');

Ovim konekcionim stringom, kreira se konekcija ka MySQL serveru koji se nalazi na lokalnom računaru, pristupa se bazi bazanovosti, korisničko ime MySQL servera je root, a lozinka je prazna (podrazumevano MySQL podešavanje).

Za zatvaranje konekcije ka bazi, dodeljuje se vrednost null promenljivoj $db:

$db = null;

Da bi se proverilo da li je povezivanje sa bazom uspešno, trebalo bi da se izvrši “hvatanje” PDOException izuzetka. On nastupa samo u slučaju da povezivanje nije uspelo (npr. Server ili baza ne postoje). Sledeći primer prikazuje fajl konekcija.php, ali ovim putem sa korišćenjem PDO ekstenzije sa MySQL bazom podataka:

Primer 20 : Povezivanje sa bazom podataka (php_pdo)

Pomoću fajla „konekcija.php“ se vrši povezivanje sa serverom na kojem je smeštena baza.

<?phptry{$db_server = "localhost";

55

Page 56: PHP MySQL Skripta

$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>Neuspešno povezivanje sa bazom!</p>".$e;exit();}?>

Za podešavanje utf-8 kodnog rasporeda, koristi se izvršavanje odgovarajućih SQL upita, kao i kod php_mysql ekstenzije. Bitno je navesti da se ti upiti izvršavaju odmah posle konekcije, pa ih je moguće uvesti u konekcioni fajl.

Za izvršavanje upita kod PDO-a postoje dve naredbe, exec() i query(). Obe izvršavaju SQL upit na serveru i ulazni parametar je SQL upit. Njihova razlika je u povratnoj vrednosti. Funkcija exec() vraća broj redova na koje se odnosi promena nakon upita (affected_rows), a query() vraća 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 izvršenog upita. Npr:

$sql="SELECT idnovost, naslov, tekst FROM novosti";$upit = $db->query($sql);

Promenljiva $upit je ovde tipa PDOStatement. U narednoj tabeli, prikazane su moguće vrednosti argumenta funkcije fetch():

Argument ZnačenjePDO::FETCH_ASSOC Vraća asocijativni nizPDO::FETCH_BOTH Vraća i numerički i asocijativni nizPDO::FETCH_BOUND Vraća TRUE i dodeljuje vrednosti kolona iz resultset-a PHP

varijablama koje su bile povezane preko bindColumn() metode. Koristi se samo zajedno sa pripremljenim upitima.

PDO::FETCH_CLASS Vraća instancu tražene klasePDO::FETCH_INTO Ažurira postojeću instancu tražene klase, mapira kolone resultset-a

sa atributima u klasiPDO::FETCH_LAZY Kombinuje PDO::FETCH_BOTH i PDO::FETCH_OBJPDO::FETCH_NUM Vraća numerički nizPDO::FETCH_OBJ Vraća podatke kao anonimni objekat

Tabela 6: PDO tipovi podataka

Naredni primer pokazuje primenu CRUD operacija, ali korišćenjem PDO-a:

56

Page 57: PHP MySQL Skripta

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><?phpinclude "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><?phpif (isset($_POST["unos"])){//Prikupljanje podataka sa forme

if (isset($_POST['naslov'])&&isset($_POST['tekst'])){$naslov = $_POST['naslov'];$tekst = $_POST['tekst'];

//Operacije nad bazominclude "konekcija.php";$sql="INSERT INTO novosti (naslov, tekst) VALUES ('".$naslov."', '".$tekst."')";if ($db->exec($sql)){echo "<p>Novost je uspešno ubačena.</p>";} else {echo "<p>Nastala je greška pri ubacivanju novosti</p>";}} else {//Ako POST parametri nisu prosleđeniecho "Nisu prosleđeni parametri!";}}}}

if (isset ($_GET['akcija']) && isset ($_GET['idnovost'])){$akcija = $_GET['akcija'];$id = $_GET['idnovost'];switch ($akcija){case "brisanje":

57

Page 58: PHP MySQL Skripta

$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 uspešno!</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>Nepostojeća 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 uspešno izmenjena.</p>";} else {echo "<p>Novost nije izmenjena.</p>";}} else {echo "<p>Nastala je greška pri izmeni novosti</p>" ;}} else {echo "<p>Nisu prosleđeni parametri za izmenu";}break;default:echo "<p>Nepostojeća akcija!</p>";

58

Page 59: PHP MySQL Skripta

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><?phpwhile ($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>

59

Page 60: PHP MySQL Skripta

6 PHP i ODBC

U PHP – u može da se napravi i ODBC (Open DataBase Connectivity) konekcija, tj. PHP skripte mogu da se povežu 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 jezičku Administrative Tools, dva puta se klikne na Data Sources (ODBC). U okviru jezička (tab) System DNS, klikne se na ADD i izabere se odgovarajući 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 Sintaksa Opisodbc_connect odbc_connect(ime baze, korisnicko

ime, sifra)Ova funkcija služi za povezivanje na bazu preko ODBC drajvera.

odbc_result odbc_result(broj polja, ime) Ova funkcija služi za čitanje podataka iz polja baze

odbc_exec odbc_exec(promenljiva u koju je zapisan upit, promenljiva za odbc konekciju)

Služi za čitanje upita preko odbc drajvera

Odbc_fetch_row Odbc_fetch_row(promenljiva) Čita podatke iz redova bazeOdbc_close Odbc_close() Služi za zatvaranje odbc

konekcije

Tabela 7: ODBC funkcije u PHP-u

60

Page 61: PHP MySQL Skripta

Indeks primera

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

Indeks tabela

61

Page 62: PHP MySQL Skripta

Tabela 1: Uporedni prikaz PHP ekstenzija za rad sa MySQL bazom......................................6Tabela 2: Uporedni prikaz InnoDB i MyISAM načina skladištenja...........................................9Tabela 3: Najčešći SQL upiti..................................................................................................15Tabela 4: MySQL funkcije......................................................................................................16Tabela 5: Tipovi podataka za pripremljene upite...................................................................53Tabela 6: PDO tipovi podataka..............................................................................................56Tabela 7: ODBC funkcije u PHP-u.........................................................................................60

Indeks slika

Slika 1: Troslojna arhitektura web aplikacija............................................................................3Slika 2: Pristup dinamičkim veb stranama...............................................................................4Slika 3: PHP ekstenzije kod WAMP servera............................................................................5Slika 4: PhpMyAdmin...............................................................................................................7Slika 5: Kreiranje nove baze....................................................................................................7Slika 6: Kreiranje tabele...........................................................................................................8Slika 7: Definisanje kolona.......................................................................................................8Slika 8: Ubacivanje novih podataka.......................................................................................10Slika 9: Pregled sadržaja tabele.............................................................................................10Slika 10: Korišćenje SQL naredbi..........................................................................................11Slika 11: Izvoz baze...............................................................................................................12Slika 12: Uvoz baze...............................................................................................................12Slika 13: Encoding podešavanja u programu Notepad ++.....................................................13

62