PHP Lekcije - lekcija 3.2 - Rad sa MySQL bazom podataka. Ubacivanje podataka INSERT INTO. Izvlačenje podataka SELECT.
U prethodnom času smo kreirali tabelu za naš sajt. U ovom času ćemo poboljšati našu tabelu i početi rad sa bazom podataka: unositi podatke i dohvatati podatke iz tabele. Mislim da neće biti ništa komplikovano, pa hajde da počnemo.
Prvo predlažem da unapredimo tabelu messages. Sada u njoj postoje polja za podatke, ali treba dodati još jedno polje za numeraciju zapisa. Ako pogledate Drupal bazu, u tabeli node postoji polje nid po kome se numerišu nodovi. Isto tako treba napraviti i za našu tabelu messages.
Idite u phpMyAdmin (http://localhost/tools/phpmyadmin za Denwer) i izmenite našu tabelu. Dodajte kolonu na početak tabele kao što je prikazano na slici:
Kolona će se zvati mid (message id), tip podataka INT (celobrojni) dužine 11. Označite opciju AUTO_INCREMENT, što znači automatsko numerisanje. Takođe postavite indeks na primary, što označava da je to primarni ključ tabele.
Ako se sećate, kreirali smo poseban metod u klasi simpleCMS za kreiranje tabele. Sada treba promeniti taj metod da doda i polje mid. Otvorite tabelu messages i kliknite na export:
Otvoriće se stranica za izvoz tabele. Izvoz je u obliku SQL upita za kreiranje i izmenu tabele. Kada menjate tabelu u phpMyAdmin, možete kopirati SQL upit za kreiranje tabele što je vrlo praktično.
Na stranici za izvoz ostavite podešavanja po defaultu i kliknite OK. PhpMyAdmin će vam prikazati SQL upit ili u pregledaču ili kao fajl. Kopirajte sledeći kod:
Obratite pažnju na kosa navodnike (backticks) koje koristi phpMyAdmin. U PHP-u možemo koristiti obične jednostruke navodnike. Kopirajte tekst u naš metod buildDB():
public function buildDB(){ $sql = "CREATE TABLE IF NOT EXISTS 'messages' ( 'mid' int(11) NOT NULL AUTO_INCREMENT, 'title' varchar(150) DEFAULT NULL, 'bodytext' text, 'created' varchar(100) DEFAULT NULL, PRIMARY KEY ('mid') ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1"; return mysql_query($sql); }
Sada probajte da ovo radi. Obrišite tabelu messages.
Potvrdite brisanje. Sada kada pokrenete index.php, pozvaće se metod buildDB() i tabela će biti ponovo kreirana.
public function buildDB(){ $sql = "CREATE TABLE Messages ( mid int NOT NULL AUTO_INCREMENT, PRIMARY KEY(mid), title varchar(15), bodytext text, created int(11) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1"; $result = mysql_query($sql); print_r($result); }
Pokrenite index.php i videćete da tabela Messages postoji kao pre.
Upiti za unos podataka INSERT INTO
Baza je spremna, sada možemo implementirati metode za unos i prikaz poruka koristeći bazu. Počnimo sa unosom u bazu. Otvorite metod write() i menjajte ga.
Unos u tabelu vrši se pomoću INSERT INTO, na sledeći način:
public function write($p) { // metod za unos poruke $sql = 'INSERT INTO Messages (title, bodytext, created) VALUES ("'. $p["title"] . '", "' . $p["bodytext"] . '", ' . time() . ')'; return mysql_query($sql); }
Hajde da objasnimo kako se vrednosti unose. SQL upit za unos počinje sa INSERT INTO, zatim ide ime tabele Messages. Posle imena tabele navodimo kolone u koje ćemo unositi podatke, primećujete da ne navodimo kolonu mid jer će MySQL automatski postaviti vrednost zbog AUTO_INCREMENT opcije. Zatim ide VALUES i navodimo vrednosti za svaku kolonu. Redosled kolona i vrednosti mora da se poklapa, kao i broj elemenata.
Ako unosimo stringove, moramo ih navesti u navodnike. Obratite pažnju da se navodnici u SQL upitu razlikuju od onih u kojima je ceo SQL upit. Takođe, kad ubacujete promenljive u SQL upit, tekst upita treba biti u jednostrukim navodnicima, a vrednosti stringova u dvostrukim unutar tog teksta, kao ovde:
"'. $p["title"] . '"
Redosled navodnika je: dvostruki, jednostruki, tačka, promenljiva, tačka, jednostruki, dvostruki.
Mislim da je primer dovoljan, biće još primera, pa ako vam nije odmah jasno, ne brinite. Sada napravite par zapisa u tabeli, zamenite metod write() sa ovim koji sam dao.
Upiti za selekciju podataka SELECT
Kreirali smo par redova, pogledajte ih u phpMyAdmin:
Sada možemo prikazati te zapise metodom display_public(), koju ćemo takođe promeniti. Izbor podataka iz tabele vrši se sa SELECT operatorom, počnimo sa jednostavnim upitom:
public function display_public() { // metod za prikaz poruka $content = ''; $sql = 'SELECT * FROM Messages'; // upit za selekciju $result = mysql_query($sql); // rezultat upita čuvamo u promenljivoj while($row = mysql_fetch_array($result)){ // rezultat treba obraditi funkcijom mysql_fetch_array() print '<div class="post">'; // div koji obavija poruku print '<span class="time">#' . $row['mid'] . ' od ' . date('d-m-Y', $row['created']) . '</span><h2>' . $row['title'] . '</h2>'; // prikazujemo vreme i naslov print '<p>' . $row['bodytext'] . '</p>'; // prikazujemo tekst poruke print '</div>'; // kraj div-a } $content .= '<p><a href="/index.php?admin=1">Dodaj poruku</a></p>'; return $content; }
Potpuno sam zamenio implementaciju metode display_public(), tako da se svi zapisi prikazuju iz baze. Objasnimo primer: upit počinje sa SELECT, * znači da želimo sva polja iz tabele. Ako napišemo:
$sql = 'SELECT mid,title FROM Messages'; // upit za selekciju $result = mysql_query($sql);
to znači da ćemo izvući samo mid i title kolone, a bodytext i created nas ne zanimaju.
Posle * ide FROM koji određuje iz koje tabele uzimamo podatke.
Rezultat mysql_query() treba čuvati u promenljivu (ovde $result), jer ćemo ga kasnije obraditi funkcijom mysql_fetch_array().
Funkcija mysql_fetch_array() vraća red po red kao niz. Prvi poziv vraća prvi red, drugi poziv drugi, itd. Kada nema više redova, vraća false. Zato koristimo while petlju da obrađujemo sve redove.
Možda je ovo teško razumeti odmah, ali sa praksom dolazi jasnoća. Nije mnogo SQL operatora pa se brzo uče.
Sortiranje u SELECT upitu ORDER BY
Možemo odrediti redosled selekcije sa ORDER BY, po defaultu rasteći, na primer:
$sql = 'SELECT * FROM Messages ORDER BY mid';
Sortiraće po rastućem mid. Za opadajuće koristimo DESC:
$sql = 'SELECT * FROM Messages ORDER BY mid DESC';
Za rastuće je ASC, mada je to default:
$sql = 'SELECT * FROM Messages ORDER BY mid ASC';
Filtriranje sa WHERE
Možemo filtrirati rezultate sa WHERE uslovom:
$sql = 'SELECT * FROM Messages WHERE mid<3 ORDER BY mid DESC';
Ovo će izvući zapise sa mid manjim od 3 (1 i 2 ako postoje). Možemo koristiti AND i OR da povežemo uslove. AND znači oba uslova moraju biti ispunjena, OR da je dovoljan jedan.
$limit_time = time() - 3600; // sat vremena unazad $sql = 'SELECT * FROM Messages WHERE mid<3 AND created>' . $limit_time . ' ORDER BY mid DESC';
Ovo dodatno filtrira zapise koji su kreirani pre manje od sat vremena. Mislim da je ovo dovoljno za sada, idemo na sledeći čas.