Omawiane zagadnienia: PHP praca z plikami, funkcje na stringach. Zadania ćwiczeniowe wykonujemy w podanej kolejności, w przypadku zawartych w nich pytań przygotowujemy odpowiedź ustnie lub pisemnie (jeśli tak wskaże prowadzący zajęcia). Po wykonaniu każdego zadania zgłaszamy ten fakt wykładowcy, po jego uwagach dokonujemy odpowiednich korekt aż do uzyskania akceptacji rozwiązania i odpowiedzi, następnie przechodzimy do następnego zadania. Przygotowanie środowiska pracy: uruchomienie programu XAMPP a następnie serwera Apache uruchomienie przeglądarki miejsce umieszczania skryptów: C:\xampp\htdocs oraz jego podkatalogi uruchomienie skryptów: przez załadowanie ich do przeglądarki adres URL http://localhost/ścieżka do skryptu Przykład 1: Księga gości (przykład z wykładu PwSI) Umieść pliki strona10.html i skrypt10.php na serwerze. Uruchom w przeglądarce plik strona10.html i zaobserwuj działanie mini księgi gości. Następnie wykonaj ćwiczenia. strona10.html <head> <meta http-equiv="content-type" content="text/html; charset=windows-1250"> <title>księga gości</title> <body bgcolor="yellow"> <p>księga Gości.</p> <p>możesz się dopisać. To co wpiszesz zostanie zapisane na dysku </p> <form method="post" action="skrypt10.php"> <p align="center"> <input type="text" name="imie" size="20"><br>imię<br> <textarea rows="2" name="wpis" cols="20"></textarea><br>treść<br> <input type="submit" value="zapisz" > <input type="reset" value="wyczyść" > </p> </form>
skrypt10.php <?php $wpis = $_POST['wpis']; $imie = $_POST['imie']; //Tu na poczatku skryptu zapiszę dany wpis do pliku ksiega.txt //Zamieniam $wpis w jedną linię ze znacznikami <br> $wpis = str_replace("\n", "<br>", $wpis); //Poniższe by wszystko było ok pod Windows (\x0d to po prostu kod \r) $wpis = str_replace("\x0d", "", $wpis); $plik = fopen("ksiega.txt","a"); fputs($plik, "$imie\n"); fputs($plik, "$wpis\n"); fclose($plik); // Zakładam, że pojedynczy wpis zajmuje zawsze 2 linie <head> <meta http-equiv="content-type" content="text/html; charset=windows-1250"> <title>księga gości</title> <body bgcolor="yellow"> <p>ksiega Gości.</p> Oto co zostało dotychczas wpisane.<br><hr> <? $licznik = 1; $plik = @fopen("ksiega.txt","r") // Ta konstrukcja - albo fopen albo exit (gdy fopen byłoby false) // jest sposobem na obsługę niepowodzeń, znak @ przy nazwie wstrzymuje // wygenerowanie komunikatu o niepowodzeniu or exit("problem z otwarciem pliku."); while (1){ //Czytam linie $linia_1 = fgets($plik); $linia_2 = fgets($plik); if(feof($plik)) break; //Wypisuję linie print("wpis nr $licznik <br>");
print("imię: <b>$linia_1 </b><br>"); print("treść wpisu:<br> <b>$linia_2</b><br><hr>"); $licznik++; } fclose($plik); Zmodyfikuj wyświetlanie wpisów tak, aby obok słów Treść wpisu: pojawiała się liczba słów, z których wpis się składa, np. Treść wpisu (12 słów):. Użyj odpowiednich funkcji stringowych. Mogą się przydać: strtok(), trim(), str_replace(). Zbuduj dodatkowo w skrypcie skrypt10.php mały formularz zbudowany z pola tekstowego i przycisku Filtruj. Jego wciśnięcie powinno wyświetlać tylko te wpisy, które w treści mają słowo wpisane do pola tekstowego. Mogą się przydać: substr_count() Zmodyfikuj odczyt wpisów z pliku tak, aby nie używać funkcji fgets(). Spróbuj użyć którejś z funkcji: file(), file_get_content()* lub fgetcsv()*. * - ta funkcja jest mało odpowiednia do tego zadania, ale jej użycie zapewnia fajną zabawę tylko dla chętnych i dociekliwych Demo rozwiązania ćwiczeń do przykładu 1: http://sigma.wsb-nlu.edu.pl/~kprzyby/lp_i/zaj_2/przyklad_1/strona10.html Przykład 2: Logowanie, wersja 2 Poniżej kod strony (ze skryptem) logującej do systemu (jest to rozwiązanie przykładu 1 z poprzedniego zestawu). Uruchom w przeglądarce i wykonaj ćwiczenia. log.php
<head> <meta http-equiv="content-type" content="text/html; charset=windows-1250"> <title>logowanie</title> <body bgcolor=teal text="#ffffff"> <br><center> <?php if(isset($_post['nazwisko'])) { if($_post['haslo']=="test") echo $_POST['imie']." ".$_POST['nazwisko'].", witamy ".($_POST['plec']=="t"?"Panią":"Pana")." w systemie "; else echo "Logowanie nieudane"; } else { // formularz generuje tylko gdy dane jeszcze nie były wysyłane <form method=post action=''> <table border=0> <tr><td>imię</td><td colspan=2> <input type=text name='imie' size=15 style='text-align: left'></td> </tr> <!-- te pola nie będą potrzebne w ćwiczeniu, zatem dopisz wtedy ten komentarz <tr><td>nazwisko</td><td colspan=2> <input type=text name='nazwisko' size=15 style='text-align: left'></td> </tr> <tr><td>płeć:</td><td>kobieta</td> <td><input TYPE="radio" NAME="plec" value="t"></td> </tr><tr><td></td> <td>mężczyzna</td><td><input TYPE="radio" NAME="plec" value="f"> </td> </tr> --> <tr><td>hasło</td><td colspan=2> <input type=password name='haslo' size=15 style='text-align:left'></td> </tr><tr> <td colspan=3> <input type=submit value='zaloguj się' style='width:200'></td> </tr> </table> </form> <? } // koniec else </center>
Tym razem załóżmy, że dane o użytkownikach są przechowywane w pliku dostep.txt, w formacie imię;nazwisko;hasło;płeć; np. dostep.txt Tomek;Fajny;ttoomm;m; Zosia;Rozważna;zzooss;k; Zmodyfikowany skrypt powinien sprawdzać zgodność podanego w formularzu imienia i hasła z tym zapisanym w pliku i wyświetlać powitanie lub informację o odrzuceniu. Mogą się przydać: split() lub explode(), Demo rozwiązania: http://sigma.wsb-nlu.edu.pl/~kprzyby/lp_i/zaj_2/przyklad_2/log.php Przykład 3: Czat (prosty) Poniżej kod strony definiującej strukturę dwóch ramek (frame), do górnej załadujemy skrypt widok.php, do dolnej czytaj.php. W górnej ramce (plik widok.php) będzie wypisywana treść rozmowy skrypt czyta dotychczasową rozmowę z pliku i ją wypisuje na stronę. Dodatkowo utworzona strona ma ustawione odświeżanie na 3 sek. Uwaga: do regularnego odświeżania strony użyto poniższego zapisu dodając go do nagłówka strony: <meta http-equiv="refresh" content="liczba_sekund"> Dolna ramka to skrypt czytaj.php, posiada formularz do podawania wpisów. Akcja tego formularza ma być ustawiona znów na czytaj.php. minichat.html <head> <title>czat</title> <frameset rows="75%,*" border=5> <frame name='gora' marginwidth=0 marginheight=10 noresize src='widok.php'> <frame name='dol' marginwidth=0 marginheight=5 noresize src='czytaj.php'> </frameset>
widok.php <head> <meta http-equiv="refresh" content="3"> <meta http-equiv="content-type" content="text/html; charset=windows-1250"> <body> <br> <? //??? - TU NAPISZ ODPOWIEDNI KOD (ODCZYTUJĄCY Z PLIKU // WYPOWIEDZI I WYŚWIETLAJĄCY JE NA STRONIE) czytaj.php <? //??? - TU NAPISZ ODPOWIEDNI KOD (ZAPISUJĄCY DO PLIKU // TO CO WPISANO DO POLA TEKSTOWEGO) <head> <meta http-equiv="content-type" content="text/html; charset=windows-1250"> <body> <br> <form> Podaj wpis <input type=text size=40 name='wpis'> <input type=submit value='wyślij'> </form> W skrypcie widok.php, w miejscu oznaczonym trzema pytajnikami napisz kod, który będzie czytał z pliku chat.txt poszczególne linie do tablicy a następnie wyświetlał je na stronie.
W skrypcie czytaj.php, w miejscu oznaczonym trzema pytajnikami napisz kod, który będzie dopisywał do odpowiedniego pliku tekst wprowadzony do formularza. Problem: Jak usunąć efekt powtarzania ostatniego wpisu przy każdorazowym odświeżaniu strony? Spróbuj coś wymyśleć (zobacz np. na funkcję header()). Mogą się przydać: wszystkie potrzebne funkcje znasz :) Demo rozwiązania: http://sigma.wsb-nlu.edu.pl/~kprzyby/lp_i/zaj_2/przyklad_3/minichat.html Przykład 4: Przeglądarka plików Poniższy skrypt generuje kod strony HTML wyświetlającej listę wyboru (element <select>) zawierającą nazwy podkatalogów pewnego, bieżącego katalogu. Po wyborze jednego z katalogów i wciśnięciu przycisku Wybierz wybrana pozycja staje się katalogiem bieżącym. Po przeładowaniu strony następuje aktualizacja listy oraz bieżącej ścieżki. Umieść skrypt na serwerze, uruchom i zaobserwuj działanie. Następnie wykonaj ćwiczenia do przykładu. lister.php <head> <meta http-equiv="content-type" content="text/html; charset=windows-1250"> <title>przeglądarka plików</title> <body bgcolor=yellow text="#000fff"> <br><center> <form method=get action=''> <table border=0> <?php if(isset($_get['plik'])) $plik = stripslashes($_get['plik']); if(isset($_get['dir'])) $dir = stripslashes($_get['dir']); else $dir=realpath("."); if(is_dir($plik)) $dir = $plik; echo "<tr><td>katalog bieżący: $dir</td></tr></table>";
chdir($dir); $katalog=opendir($dir); echo "<table border=0> <tr><td align=left>wybierz plik: <select name='plik'>"; while (false!== ($p = readdir($katalog))) { // $p reprezentuje kolejny plik (lub podkatalog) z katalogu if(is_dir($p)) echo "<option value='".realpath($dir."/".$p)."'".($plik==$p?' selected':'').">".$p." [DIR] </option>"; } closedir($katalog); echo "</select></td>"; echo "<input type='hidden' name=dir value='".$dir."'>"; echo "<td align=center> <input type=submit value='wyświetl'> </td>"; </tr></table> </form></center> Uzupełnij kod tak, aby w liście wyboru, poza katalogami, wyświetlał także pliki. Po wyborze pliku i wciśnięciu przycisku wysłania formularza poniżej powinna wyświetlić się treść pliku (z zachowaniem podziału na linie) z ponumerowanymi liniami. Dodaj na stronie kolejny formularz z polami wymaganymi do uploadu plików oraz przyciskiem Dodaj plik. Jego wciśnięcie powinno wykonać upload wybranego, lokalnego pliku do katalogu wybranego w liście jako bieżący. Dodaj na stronie trzeci formularz z polem tekstowym oraz przyciskiem Wyszukaj. Powinien pokazywać się tylko podczas wyświetlania treści pliku. Wciśnięcie przycisku powinno wyszukać i wyróżnić (np. innym, wyraźnym
kolorem) wszystkie frazy występujące w tekście takie jak fraza wprowadzona do pola tekstowego. * Uwaga: Ćwiczenia oznaczone gwiazdką proszę traktować jako uzupełniające, do wykonania po ćwiczeniach obowiązkowych w całym zestawie (chyba że prowadzący zajęcia zaleci inaczej). Ćwiczenie*: Rozszerz poprzednie ćwiczenie na dowolne wyrażenie regularne. Ćwiczenie*: Spróbuj usunąć przycisk i do wysłania formularza wykorzystywać zdarzenie wyboru elementu z listy (użyj obsługi zdarzenia przez Javascript). Z PHP mogą się przydać funkcje: isset, opendir, readdir, is_file, closedir, file, htmlspecialchars, realpath, chdir, is_dir, stripslashes. Z Javascript może się przydać: zdarzenie onchange, metoda submit(), odwołanie w Javascript do formularza. Demo rozwiązania: http://sigma.wsb-nlu.edu.pl/~kprzyby/lp_i/zaj_2/przyklad_4/lister.php Przykład 5 (praca samodzielna): Lista towarów, wersja 5 Utwórz stronę ze skryptem do podstawowej obsługi (dodawanie i wyświetlanie) listy towarów. a. Strona powinna zawierać formularz do wprowadzenia: nazwy, ceny netto i stawki vat. Po wciśnięciu przycisku zatwierdzającego formularz dane powinny zostać dopisane do pliku (każdy towar w nowej linii w formacie: nazwa cena vat). b. Poniżej formularza skrypt powinien wypisywać (w tabeli HTML) wszystkie wcześniej dodane towary (przechowywane w pliku). Może się przydać: isset(), is_numeric(), fopen(), fclose(), fputs(), flock(), header(), fgetcsv(), number_format(). Dodatek dla dociekliwych: Spróbuj zabezpieczyć sytuację jednoczesnego zapisywania do pliku przez kilku użytkowników strony. Wcześniej przeczytaj w manualu PHP o funkcji flock(). Demo rozwiązania: http://sigma.wsb-nlu.edu.pl/~kprzyby/lp_i/zaj_2/przyklad_5/towary5.php
Przykład 6 (praca samodzielna): Licznik odwiedzin Napisz stronę zawierającą licznik odwiedzin. Aktualna liczba odwiedzin przechowywana jest w pliku. Każde wejście na stronę uruchamia skrypt, który odczytuje z pliku, zwiększa o jeden, wyświetla na stronie i zapisuje do pliku zaktualizowaną wartość. Może się przydać: file_exists(), fopen(), fgets(), fputs(), fclose(), flock(), header() Demo rozwiązania: http://sigma.wsb-nlu.edu.pl/~kprzyby/lp_i/zaj_2/przyklad_6/licznik.php Inne rozwiązanie, wykorzystujące mechanizm ciasteczek, zostało zaprezentowane jako przykład (skrypt15.php) na wykładzie z PwSI.