PHP Lekcije - lekcija 2 - Rad sa fajlovima: otvaranje, upisivanje, čitanje.
U prethodnom času smo napravili kostur za naš gostujući dnevnik, blog ili čet. Sada treba da dodamo funkcionalnost. U ovom času ćemo zapisivati naše unose u fajlove i prikazivati unose iz fajlova.
PHP poseduje mnogo funkcija za rad sa fajlovima, mi ćemo razmotriti neke od njih. Verovatno će vaš sajt u realnosti zapisivati podatke u bazu podataka (u to sam siguran), tako da ćemo razmotriti samo neke funkcije da biste razumeli suštinu. Rad sa bazom ćemo proučiti kasnije.
Ako nemate fajlove koje smo pravili u prethodnom času, vratite se i skinite ih.
Idemo na formu za dodavanje unosa:
/index.php?admin=1
Sa ove forme ćemo dodavati unose. Da bismo ih obradili, potrebno je na stranici index.php (na koju forma šalje podatke) proveriti da li postoji sadržaj u promenljivoj $_POST. To se lako proverava:
if($_POST){ }
Jednostavno, zar ne? Unutar viticastih zagrada treba staviti obradu niza $_POST. Nećemo pisati kod direktno u viticastim zagradama, već ćemo taj kod smestiti u našu klasu, i pozivaćemo ga preko metoda objekta. U fajlu index.php pozivamo metod:
if($_POST){ $obj->write($_POST); }
U fajlu simpleCMS.php implementacija metode write() će izgledati ovako:
public function write($p) { // metod za upis poruke }
Zašto ovo radimo? Da bismo smanjili kod u index.php. Taj fajl treba da služi samo za upravljanje, dok obrada nizova i prikaz podataka treba da bude u posebnom fajlu, na primer u klasi simpleCMS. Ova podela poboljšava organizaciju koda i olakšava razumevanje, kako drugima, tako i vama samima.
Počnimo sa jednostavnim – štampanjem niza $_POST koji je poslat sa forme. Umetnite ovaj kod:
public function write($p) { // metod za upis poruke print_r($p); }
Kao što vidite, koristimo lokalnu promenljivu $p, iako u parametre metode stiže superglobalni $_POST. Ne koristimo $_POST direktno, jer u drugim slučajevima možemo hteti da unosimo podatke iz XML fajla ili nekog drugog izvora. Korišćenjem lokalne promenljive unosimo fleksibilnost i opštu upotrebljivost metode.
Popunite formu i pošaljite je. Moj niz je izgledao ovako:
Array ( [title] => Ivan [bodytext] => Zdravo, svete! )
Ako ste uneli drugačije podatke, vaš niz će biti drugačiji. Prikazali smo niz da vidimo koje ključeve možemo koristiti: $p['title'] i $p['bodytext']. Sada znamo koje podatke imamo i možemo ih upisati u fajl. Počinjemo sa upisivanjem u fajl.
PHP upis u fajl
Pre nego što upišemo u fajl, potrebno je „otvoriti ga za upis“. To znači povezati fajl sa PHP promenljivom. Sve što radimo sa fajlom u PHP je kroz promenljivu tipa resource. Evo šta to znači:
public function write($p) { // metod za upis poruke $message = fopen("messages/file.txt","w"); print_r($message); }
Kreirao sam fajl file.txt u folderu messages. Kada popunimo formu i pošaljemo, dobićemo:
Resource id #4
Resource je tip promenljive $message, a 4 je ID ove promenljive među ostalim resursima. Sve akcije nad $message automatski se odražavaju u fajlu. Upisivaćemo u fajl red po red, kako bismo kasnije mogli da čitamo liniju po liniju:
public function write($p) { // metod za upis poruke $message = fopen("messages/file.txt","w"); fputs ($message, $p['title']. "\r\n"); fputs ($message, $p['bodytext']); }
Simboli \r\n u dvostrukim navodnicima znače novi red, pa će u file.txt biti tekst:
Ivan
Zdravo, svete!
Nakon radnje nad fajlom, treba zatvoriti fajl da se oslobodi memorija:
public function write($p) { // metod za upis poruke $message = fopen("messages/file.txt","w"); // otvaramo fajl fputs ($message, $p['title']. "\r\n"); fputs ($message, $p['bodytext']); fclose ($message); // zatvaramo fajl }
Verovatno ste primetili da se fajl svaki put prepisuje – to zavisi od parametra u fopen. Možemo i dopisivati fajl ili ga samo čitati. Na primer:
$message = fopen("messages/file.txt","r"); // otvaramo fajl samo za čitanje
- r – otvaranje fajla samo za čitanje.
- r+ - otvaranje fajla za čitanje i pisanje.
- w – kreira novi prazan fajl. Ako fajl već postoji, briše ga.
- w+ - kao r+, ali briše postojeći fajl.
- a – otvara postojeći fajl za pisanje, pozicionira se na kraj fajla.
- a+ - otvara fajl za čitanje i pisanje, pozicionira se na kraj, ne briše sadržaj.
Kao što piše, ako otvorimo fajl sa w, kreira se novi fajl ili briše postojeći. Sada ćemo imenovati fajlove po vremenu dobijenom funkcijom time().
Funkcija time() vraća broj sekundi od 1. januara 1970. godine.
Dobija se nešto kao:
public function write($p) { // metod za upis poruke $message = fopen('messages/'.time(),"w"); // otvaramo fajl fputs ($message, $p['title']. "\r\n"); fputs ($message, $p['bodytext']. "\r\n"); fputs ($message, time()); fclose ($message); // zatvaramo fajl }
Svake sekunde time() vraća veći broj, pa fajlovi dobijaju sve veće ime. Dodajte više unosa i videćete fajlove u folderu messages. Sada treba da čitamo fajlove i prikazujemo unose.
PHP čitanje fajla
Da bismo čitali fajl, otvaramo ga za čitanje sa fopen i parametrom 'r'. Svi fajlovi su u folderu messages. Da bismo pročitali sve fajlove, koristićemo petlju while (dok fajlovi postoje).
Pregled fajlova u folderu vršimo funkcijom opendir() koja otvara folder za čitanje:
if (is_dir('messages')) { // proveravamo da li postoji folder if ($dh = opendir('messages')) { // otvaramo folder za čitanje while (($file = readdir($dh)) !== false) { // dok ima fajlova ih čitamo // ovde izvršavamo željene operacije } closedir($dh); // zatvaramo folder } }
Imena fajlova dobijamo funkcijom readdir(), koja se čuva u promenljivoj $file. Nakon završetka zatvaramo folder radi oslobađanja memorije.
Sada kad možemo da čitamo fajlove, doradićemo metod display_public():
public function display_public() { // metod za prikaz poruka $content = ''; if (is_dir('messages')) { // proveravamo postojanje foldera if ($dh = opendir('messages')) { // otvaramo folder za čitanje while (($file = readdir($dh)) !== false) { // dok ima fajlova čitamo if(substr($file, -4) == '.txt'){ // uzimamo samo .txt fajlove $filename = 'messages/' . $file; // puno ime fajla $message = fopen($filename, 'r'); // otvaramo fajl za čitanje $title = fgets($message); // čitamo prvi red $body = fgets($message); // čitamo drugi red $time = fgets($message); // čitamo treći red print '<div class="post">'; // div koji obavija poruku print '<span class="time">' . date('d-m-Y', $time) . '</span><h2>' . $title . '</h2>'; // prikazujemo vreme i naslov print '<p>' . $body . '</p>'; // prikazujemo tekst poruke print '</div>'; // kraj div-a fclose($message); // zatvaramo fajl } } closedir($dh); // zatvaramo folder } } $content .= '<p><a href="/index.php?admin=1">Dodaj poruku</a></p>'; return $content; }
Okomentarisao sam svaku liniju, ako nešto nije jasno, pišite u komentarima i razjasniću.
Ne mislim da će vam u praksi trebati čitanje fajla po linijama, ali za razumevanje rada PHP funkcija i rada sa fajlovima i folderima ovi časovi su korisni.
Ispod je izvorni kod za naš međufazni sajt.