PHP - Povezivanje skripti sa MySql bazama podataka
Uvod
U prethodnim člancima upoznali smo se sa time koliku važnost baze podataka imaju u oblasti dizajna i održavanja web sajtova, kao i sa tim da je povezivanje sa bazama podataka jedan od glavnih zadataka serverskih jezika (među kojima je i PHP).
Još jednostavnije, može se reći da bez baza podataka nije moguće (u iole praktičnom smislu): kreirati online prodavnice, forume, blogove, chat aplikacije i mnoge druge online servise - i stoga ćemo odmah preći na glavni zadatak.
Kroz članak koji je pred nama, upoznaćemo se sa tehnikama za povezivanje PHP skripti sa MySql bazama, i procedurama za upis, čitanje, ažuriranje i obradu podataka.
PHP i MySql - Ostvarivanje veze i kreiranje baze
Što se tiče tehničkih preduslova za pristup MySql bazama preko PHP-a, stvari su prilično jednostavne: pod uslovom da već koristite paket XAMPP (onako kako smo opisali u prethodnim člancima), moći ćete da pristupate MySql bazama podataka preko PHP skripti, bez potrebe za dodatnim podešavanjem servera. *
Da bismo mogli da se bavimo čitanjem, upisom i obradom podataka iz određene baze podataka, potrebno je prvo uspostaviti vezu sa serverom i (potom), otvoriti postojeću bazu, ili kreirati novu. **
Povezivanje sa serverom
Kreirajte datoteku 01_povezivanje_proba.php
(naravno, kao i do sada, ceo projekat smestite u zaseban folder sa prikladnim imenom), i zatim unesite sledeći sadržaj:
Preko komande mysqli_connect
moguće je povezati se: sa serverom, ili direktno sa konkretnom bazom podataka na serveru (ovoga puta povezujemo se sa serverom; uskoro ćemo se povezivati direktno sa bazom podataka koju ćemo u međuvremenu kreirati).
Pri pozivu funkcije mysqli_connect
navode se tri ili četiri parametra: naziv servera, korisničko ime, lozinka i - po potrebi (što ovoga puta nismo uradili) - naziv baze.
- naziv servera
localhost
odgovara lokalnom serveru koji se pokreće preko paketa XAMPP - za povezivanje sa online bazama, koristi se odgovarajući naziv servera (ili IP adresa)
- korisničko ime
root
označava korisnika sa maksimalnim nivoom privilegija i tipično se koristi za povezivanje sa lokalnom bazom u fazi isprobavanja sajta (međutim ....) - ukoliko određenu skriptu planiramo da koristimo na online serveru, praktičnije je koristiti drugi korisnički nalog sa nižim nivoom privilegija (s tim da je potrebno unapred pripremiti takav nalog na serveru i (naravno), potrebno je da nivo privilegija naloga bude dovoljno visok da omogući neometan rad sa bazom)
- lozinka "" (prazna niska), takođe je krajnje adekvatna (i uobičajena) pri povezivanju sa lokalnim MySql serverom, dok je u slučaju povezivanja sa online serverom, potrebno koristiti odgovarajuću lozinku (koja je deo korisničkog naloga na serveru)
Ukoliko se veza sa serverom uspešno uspostavi (odnosno, veza sa bazom, kao što ćemo videti u budućim primerima), funkcija mysqli_connect
kreira objekat sa parametrima veze, čija se referenca (promenljiva koja se tipično naziva $veza
), može dalje predavati ostalim funkcijama za obradu podataka iz MySql baze.
Ukoliko dođe do greške u povezivanju, promenljiva $veza
dobija vrednost null
, i stoga je uvek prvo potrebno proveriti stanje objekta $veza
pre nego što pokušamo da izvedemo bilo kakav 'zahvat' koji podrazumeva povezanost sa bazom.
Kreiranje baze podataka
Kada se utvrdi da je veza sa MySql serverom uspešno ostvarena, može se kreirati i nova baza podataka na (lokalnom) serveru.
Upit se zapisuje u obliku niske ('kao i inače'), a pokreće se preko komande mysqli_query
:
Objekat $rezultat
, u idejnom smislu slično kao i objekat $veza
, sadrži rezultat izvršavanja upita, i upravo se preko objekta $rezultat
može proveriti da li je upit uspešno izvršen.
Skripta koju smo videli je "školska" skripta, čija je svrha: upoznavanje sa načinom povezivanja PHP skripti sa MySql serverom i (takođe), sa procedurom za kreiranje nove baze - i stoga je sasvim opravdano (i očekivano), da skripta ispisuje (sve) poruke o uspešnom povezivanju sa serverom i uspešnom kreiranju baze podataka, ali - to nije pristup koji u svakodnevnoj praksi deluje elegantno ....
Direktno povezivanje sa bazom
U praksi, nije potrebno korisnike "svaki čas" obaveštavati o tome da se PHP skripta uspešno povezala sa bazom, jer - to je nešto što se u svakodnevnim uslovima eksploatacije podrazumeva (i ne predstavlja korisno obaveštenje: ni za korisnike sajta, ni za administratore koji sajt održavaju).
Skriptu (odnosno if
grananje koje smo koristili), prepravićemo tako da poruka bude ispisana samo ukoliko dođe do greške pri povezivanju - što je jedina prava informacija za administratore sajta (koji u takvoj situaciji treba da ustanove zašto je do greške došlo).
Budući da će se skripta ovoga puta povezivati direktno sa bazom koju smo u prethodnom odeljku kreirali (i budući da prikazujemo praktičnu verzija skripte kakvu ćemo inače koristiti nadalje u članku i budućim člancima), kreirajte novu datoteku sa nazivom povezivanje.php
i unesite sledeći kod:
Sada se skripta povezivanje.php
može koristiti u drugim skriptama koje pišemo.
Kreiranje tabele sa podacima i upis sadržaja
Zarad upoznavanja sa komandama iz PHP-a koje se tipično koriste u radu sa bazama podataka, kreiraćemo i popuniti tabelu sledeće strukture i sadržine:
Primer je vrlo jednostavan, ali - sasvim dovoljan za upoznavanje sa osnovnim principima.
Kreiranje strukture tabele
Napravite novu skriptu sa nazivom 02_kreiranje_tabele.php
i unesite sledeći kod:
Kod sa gornje slike predstavlja običan MySql upit sledećeg oblika ....
.... koji se bazi prosleđuje preko PHP instrukcija, pa - ukoliko skripta ne vrati poruku o grešci - možemo nastaviti dalje ....
Popunjavanje tabele
Kreirajte novu skriptu sa nazivom 03_popunjavanje_tabele.php
i unesite sledeći sadržaj:
I ovoga puta korišćen je jednostavan SQL upit, ali, takođe je prosleđena vrednost promenljive $naziv_tabele
.
Prosleđivanje vrednosti promenljivih preko upita
Prosleđivanje vrednosti promenljivih preko upita, nije nikakva "specijalnost" koja se može koristiti samo u funkcijama za rad sa bazama podataka, već (da se podsetimo), deo osnovne PHP sintakse koja važi uvek.
U opštem smislu, PHP dozvoljava da se promenljive direktno navedu unutar niski (koje su uokvirene navodnicima), a niske ovoga puta predstavljaju (My)SQL upite:
Niske i promenljive znakovnog tipa se predaju uz navođenje naziva promenljive između apostrofa, dok se promenljive brojčanog tipa navode bez apostrofa (upravo onako kako je i inače praksa u MySql upitima).
Unutar niski "pod navodnicima" (pri pokretanju skripte): identifikatori (tj. nazivi) promenljivih, zamenjuju se vrednostima promenljivih - posle čega se praktično pokreću upiti na MySql serveru.
Čitanje podataka iz baze
Moglo bi se reći da su u prethodnim slučajevima sami SQL upiti bili nešto komplikovaniji (zapravo, samo obimniji), pri čemu je način pozivanja upita preko PHP-a, bio krajnje jednostavan, dok - u slučaju pozivanja upita za čitanje sadržaja tabele - nailazimo na 'obrnutu' situaciju.
Da budemo precizni: upiti za čitanje su (tipično) jednostavniji (od prethodnih upita), ali, procedura za obradu podataka - koja sledi posle upita za čitanje - ipak je ponešto kompleksnija (mogli bismo reći da nije nimalo komplikovana, međutim, često zna da zada muke programerima koji se prvi put susreću sa tematikom, i stoga ćemo pokušati da postupak predstavimo na što jednostavniji način) ....
Osnovni format skripte za čitanje podataka
Za početak, možemo uneti sledeći kod u novu datoteku sa nazivom 04_citanje_podataka.php
:
Ukoliko dođe do greške * prilikom izvršavanja funkcije mysqli_query
(u slučaju da je upit pogrešno formatiran, da se pozivamo na bazu ili tabelu koja ne postoji i sl), objekat $rezultat
imaće vrednost null
.
U suprotnom, objekat $rezultat
sadržaće tabelu, koja se može čitati red-po-red, i čiji nazivi kolona odgovaraju nazivima polja MySql tabele (sa asocijativnim nizovima smo se upoznali u prethodnim člancima o superglobalnim promenljivama).
Za čitanje ćemo koristiti komandu mysqli_fetch_assoc
, * koja čita 'sledeći' red tabele i kreira asocijativni niz, koji se popunjava sadržajem pročitanih polja (pri čemu se indeksi niza poklapaju sa nazivima polja iz MySql tabele); naravno - sve pod uslovom da podaci za čitanje postoje.
O tome da li je funkcija mysqli_fetch_assoc
vratila očekivani rezultat - mora se uvek voditi računa (u nastavku ćemo se pozabaviti mehanizmima provere), ali, budući da znamo da tabela koju razmatramo sadrži bar jedan red, "zažmurićemo" još malo i posmatraćemo skriptu za čitanje u najosnovnijem obliku. **
Dopunite gornju skriptu sledećim sadržajem (i potom pokrenite skriptu):
Pokretanjem skripte dobija se sledeći ispis:
Komanda mysqli_fetch_assoc
pronašla je i pročitala prvi red tabele i smestila podatke u objekat $red
(koji je formatiran kao asocijativni niz), i stoga nije bilo poteškoća da se vrednosti iz takvog niza iskoriste u ispisu.
Međutim (kao što smo prethodno nagovestili), nije dovoljno pročitati samo jedan red (tj. prvi red), već je potrebno pročitati celu tabelu i upotrebiti sve podatke iz tabele.
Provera učitanih podataka
U uobičajenim okolnostima ("dokle god ima podataka za čitanje"), komanda mysqli_fetch_assoc
čita (odnosno vraća), naredni red tabele, pri čemu se pokazivač za čitanje pomera za jedan red unapred (ili, praktičnije - jedan red "nadole").
Međutim, ukoliko se komanda poziva onda kada nema (više) redova za čitanje, nastaje sledeća situacija:
- krajnji rezultat izvršavanja komande
mysqli_fetch_assoc
je vrednostnull
- vrednost
null
dodeljuje se promenljivoj$red
- ako bismo se (na kraju) obratili određenom indeksu (primera radi,
$red['ime']
) - došlo bi do greške u izvršavanju skripte!
Da bi takav nepovoljni ishod bio izbegnut, potrebno je proveravati stanje objekta $red
posle čitanja (odnosno, pre obraćanja određenom indeksu iz tabele):
Sada sledi pravi "rasplet" ....
U prvom slučaju, nije bilo provere, dok smo u drugom slučaju proverili i ispisali samo jedan red, a zadatak je (i dalje) - obići sve redove.
Obilazak "cele linearne strukture" najčešće podrazumeva korišćenje petlje (a tako će biti i ovoga puta), i ostaje samo pitanje - kako zapisati kod.
Prvo je potrebno razumeti da je while
petlja - na osnovnom tehničkom nivou - skoro isto što i if
struktura bez false
grane koja se posle izvršenog bloka komandi vraća na ispitivanje uslova (naravno, ako je uslov za ulazak u telo petlje uopšte bio zadovoljen).
Kada to sve razumemo, možemo kod sa prethodne slike dopuniti i prepraviti, tako da se ispitivanje uslova na prirodan način uklopi u strukturu while
petlje (prikazujemo sada celokupnu skriptu 04_citanje_podataka.php
, sa komentarima):
U nastavku, dodatno ćemo ilustrovati objašnjenja koja ste mogli pročitati u komentarima u gornjem odeljku.
Ilustracija principa funkcionisanja while petlje za čitanje sadržaja MySql tabele
Pre prvog poziva, pokazivač stoji na početku tabele i skripta je spremna da čita prvi red, to jest - "sledeći" red (naravno, za sada nije poznato ni da li "prvi" red, ili "sledeći" red, uopšte postoji).
Kada se pozove komanda mysqli_fetch_assoc
, objekat $red
dobija konkretnu vrednost, * to jest, postaje asocijativni niz (bar u konkretnom primeru), a tabelarni pokazivač se pomera na početak sledećeg reda.
Budući da je uslov u while
petlji zadovoljen, ulazi se u ciklus petlje i program ispisuje prvi blok teksta:
Potom se postupak ponavlja: po izvršenom ciklusu, skripta se vraća na ispitivanje uslova, međutim, ispitivanju uslova prethodi učitavanje reda (odnosno, 'pokušaj' učitavanja reda).
U konkretnom primeru, komanda mysqli_fetch_assoc
(ponovo) pronalazi novi red u tabeli, objekat red$
se popunjava sadržajem, a pokazivač prelazi na sledeći red tabele.
Uslov u while
petlji je zadovoljen (red nije prazan), ponovo se ulazi u telo petlje, a u ispis se dodaje drugi blok:
Prelazi se na čitanje poslednjeg reda (naravno, "mi" vidimo i znamo da sadržaj reda postoji, i vidimo da je (praktično) u pitanju poslednje čitanje reda i poslednji ispis, dok program još uvek nema "takva saznanja") ....
Ponovo komanda mysqli_fetch_assoc
pronalazi novi red u tabeli, popunjava se objekat $red
, a pokazivač prelazi na početak sledećeg reda - koji je prazan.
U svakom slučaju, uslov za ulazak u petlju je i ovoga puta zadovoljen (u promenljivu $red
, i dalje je učitan sadržaj poslednjeg reda), još jednom se ulazi u telo petlje - pri čemu se u ispis dodaje i treći blok:
Na kraju, sledi "zaključak": poziva se ("poslednji put"), komanda mysqli_fetch_assoc
....
.... ali ovoga puta komanda ne pronalazi sadržaj, i stoga se objektu $red
dodeljuje vrednost null
.
Budući da uslov za ulazak u telo petlje - nije zadovoljen - prekida se dalje izvršavanje while
petlje, a program prelazi na sledeću naredbu (ili, u konkretnom primeru, budući da nema sledeće naredbe - završava se izvršavanje skripte).
Ostale operacije
Sada kada poznajemo principe po kojima se PHP skripte povezuju sa bazama podataka i kada razumemo mehanizme za prosleđivanje podataka, osvrnućemo se ukratko i na kreiranje drugih skripti: za ažuriranje i uklanjanje slogova, za dodavanje novih kolona u tabele i sl.
Ažuriranje slogova
Kreirajte novu datoteku sa nazivom 03_azuriranje_slogova.php
i unesite sledeći kod:
Ako ste isprobali skriptu, lako možete zaključiti da je princip isti kao i do sada (i da se menja samo oblik upita).
Princip = upit se prosleđuje bazi, i potom se proverava da li je upit korektno izvršen.
Uklanjanje slogova
Kreirajte novu datoteku sa nazivom 04_uklanjanje_slogova.php
i unesite sledeći kod:
SQL upit za uklanjanje slogova je veoma jednostavan, ali, recimo da bi ovo moglo biti dobro mesto za jednu veoma važnu napomenu: ukoliko zaboravimo uslov (u konkretnom primeru: ".... WHERE id=4
"), biće obrisani svi slogovi u tabeli!
U uvodnom članku o bazama podataka već smo se osvrnuli na to da je potrebno postupati vrlo pažljivo sa komandama za ažuriranje slogova - a pogotovo sa komandama za uklanjanje slogova i tabela, ali, od ponavljanja takvih uputstava - nikako ne može biti štete! :)
Dodavanje novih kolona u tabelu
Tabelu sa podacima o učenicima, proširićemo dodavanjem polja za e-mail adresu, koje smo na početku "prevideli" (da bismo imali o čemu da pišemo u ovom poslednjem poglavlju :)) - pri čemu ćemo koristiti sledeći kod:
Naravno, na ovom mestu se susrećemo sa jednim omanjim problemom: sva polja u koloni email
potrebno je popuniti podacima, ali, sama MySql sintaksa neće biti od prevelike pomoći pri automatizaciji tog zadatka.
Međutim, budući da koristimo skriptni jezik koji ima na raspolaganju kontrolne strukture (grananja i petlje), prethodno navedeni zadatak može se rešiti prilično lako - uz malo promišljanja (ali, to ćemo ipak ostaviti za neku drugu priliku (to jest, ažuriranju kolona u tabeli, uskoro ćemo posvetiti kraći zaseban članak)).
Za kraj ....
Nadamo se da smo, kroz primere koje smo prikazali, uspeli da "demistifikujemo" proceduru povezivanja PHP skripti sa MySql bazama podataka, koja početnicima u oblasti back-end programiranja ponekad zadaje muke (reklo bi se - prilično nepotrebno). :)
Zarad utvrđivanja gradiva, predlažemo da kreirate:
- novu bazu sa drugačijom strukturom (pri čemu ćete samostalno kreirati skripte za povezivanje)
- skripte za kreiranje tabela i upis podataka
- skriptu za čitanje i ispis podataka
.... ali ovoga puta kreirajte ispis u obliku tabele (uz korišćenje CSS-a i pravila za kombinovanje HTML i PHP koda unutar PHP skripti, o kojima smo govorili u prethodnim nastavcima).
Srećno!