Na pewno nie raz spotkałeś się w Internecie z księgą gości, ankietą, sondą itd. A czy zastanawiałeś się kiedyś nad tym, gdzie są przechowywane zebrane z formularzy dane? Możemy tego dokonać za pomocą dwóch sposobów.
Jednym z nich są właśnie operacje na plikach tekstowych. Można także korzystać z baz danych, ale o tym w innym artykule. No więc, aby móc operować na plikach musisz mieć dostęp na serwerze do funkcji tj.: fopen() lub file(). To właśnie dzięki nim będziesz mógł pobierać i zapisywać dane w plikach tekstowych. Być może zmyli Cię trochę wyrażenie ‘pliki tekstowe’. Nie muszą to być pliki z rozszerzeniem ‘.txt’ – jest ono dowolne, np. ‘.ppp’, ‘.cos’ itd. Nie ma to wpływu na przechowywane informacje. Skoro wiesz jakie funkcje są niezbędne do wykonywania operacji na plikach i masz do nich dostęp to zapoznaj się z innymi, które będą nam niezbędne:
fopen(); – otwiera plik
file(); – pobiera cala zawartość pliku i zapisuje ją do tablicy
fread(); lub fgets(); – pobiera dane z pliku
fgetc(); – pobiera jeden znak z pliku
fwrite(); lub fputs(); – wstawia dane do pliku
flock(); – blokuje dostęp do pliku
fclose(); – zamyka plik
file_exists(); – sprawdza czy podany plik istnieje
fseek(); – przemieszcza wewnętrzny wskaźnik pliku
feof(); – sprawdza czy osiągnięto koniec pliku
ftell(); – zwraca położenie wewnętrznego wskaźnika pliku
rewind(); – ustawia wewnętrzny wskaźnik na początku pliku
Już wiesz, które funkcje będą przez nas wykorzystywane. Teraz możemy przejść do rzeczy…
1. Otwieranie pliku
Aby pobrać dane z pliku musimy go najpierw otworzyć. Są dwie funkcje, które nam to umożliwiają, różnią się jednak zastosowaniem. Pierwsza z nich fopen() otwiera plik o podanej nazwie, ale dostosowuje się do wskazanego trybu. Wyróżniamy 6 trybów, które opisuje poniżej:
w – otwarcie tylko do zapisu. Istniejące dane są tracone; jeśli plik nie istnieje, PHP próbuje go utworzyć.
w+ – otwarcie do zapisu i odczytu. Istniejące dane są tracone; jeśli plik nie istnieje, PHP próbuje go utworzyć.
r – otwarcie tylko do odczytu. Znacznik pozycji jest umieszczony na początku pliku.
r+ – otwarcie do odczytu i zapisu. Znacznik pozycji jest umieszczony na początku pliku.
a – otwarcie pliku do dołączenia. Dane są dopisywane na końcu istniejącego pliku; jeśli plik nie istnieje, PHP próbuje go utworzyć.
a+ – otwarcie do dołączenia i odczytu. Dane są dopisywane na końcu istniejącego pliku; jeśli plik nie istnieje, PHP próbuje go utworzyć.
Zastosowanie każdego z podanych wyżej trybów objaśnię na przykładach w późniejszych etapach.
Na samym początku musimy stworzyć plik z danymi. Służy nam do tego pierwszy (‘w’) lub drugi (‘w+’) tryb. Można także skorzystać z trybó ‘a’ i ‘a+’, ale są one żadko do tego używane.
$plik = fopen(‘dane.txt’, ‘w’); lub $plik = fopen(‘dane.txt’, ‘w+’); |
Dzięki tak zastosowanej funkcji utworzyliśmy plik o nazwie ‘dane.txt’, a wskaźnik na ten plik przypisaliśmy zmiennej $plik. Różnica między zastosowaniem trybu ‘w’ i ‘w+’ polega na tym, że ten pierwszy tworzy plik i otwiera go tylko do zapisu, a ten drugi oprócz tworzenia i zapisu umożliwia także odczyt danych ze środka. Musisz jednak uważać przy stosowaniu tego trybu. Jeśli będziesz próbować utworzyć plik, który już istnieje to zostanie on nadpisany i zawartość poprzedniego zostanie usunięta. Jeśli boisz się o stratę danych to przed każdym tworzeniem pliku możesz zastosować funkcje file_exists(), która sprawdza czy podany plik istnieje i zwraca ‘true’ w przypadku powodzenia lub ‘false’ w przypadku nie odnalezienia. Tak więc podaną wyżej konstrukcje możemy zapisać tak:
$plik_dane = ‘dane.txt’; // przypisanie adresu pliku do zmiennej if (file_exists($plik_dane)) { print “Podany plik już istnieje!”; } else { $plik = fopen($plik_dane, ‘w’); print “Plik o nazwie <b>$plik_dane</b> został utworzony!”; } |
Pamiętaj, że dobrym zwyczajem po zakończeniu pracy z plikiem jest jego zamknięcie. Służy ku tym celom funkcja fclose(). Jako jej parametr podajesz tylko nazwę wskaźnika pliku, który został utworzony w wyniku działania funkcji fopen(). Dla ułatwienia przedstawię to na przykładzie:
$plik_dane = ‘dane.txt’; // przypisanie adresu pliku do zmiennej if (file_exists($plik_dane)) { print “Podany plik już istnieje!”; } else { $plik = fopen($plik_dane, ‘w’); print “Plik o nazwie <b>$plik_dane</b> został utworzony!”; fclose($plik); } |
Skoro już wiesz jak stosować funkcje fopen() to przejdźmy do drugiej metody otwierania pliku. Ma ona nieco inną budowę, ale bardziej ograniczoną. Służy ona tylko do otwierania już istniejących plików i przypisywania jego zawartości do tablicy. Każdy wiersz pliku to osobny indeks. Tak wiec stosując instrukcje:
$plik = file(‘dane.txt’);
całą zawartość pliku zawiera teraz tablica $plik, w której każdy indeks to kolejny wiersz. Zmienna $plik ma tyle indeksów, ile jest wierszy w pliku, ale pamiętaj że tablice są indeksowane od ‘0’.
Wiesz już jak otwierać plik, więc teraz spróbuję wytłumaczyć Ci na czym polega zapis i odczyt danych.
2. Zapis i odczyt danych do pliku
Do zapisu danych do pliku będzie na pomocna funkcja fwrite() lub jej odpowiednik fputs(). Funkcje te mają podobną konstrukcje i ich stosowanie jest zależne od woli programisty. Ja dla przykładów będę stosował jej najczęściej używaną formę czyli fwrite(). To samo stwierdzenie zachodzi przy odczycie danych. Służą do tego funkcje fread() i fgets(). Tutaj także będę stosował tą pierwszą formę.
Bardzo ważny przy zapisywaniu i odczytywaniu danych jest tryb w jaki został otworzony plik. Jeśli był to tryb ‘w’ lub ‘w+’ wewnętrzny wskaźnik położenia w pliku ustawiany jest na początku i zapis oraz odczyt zaczyna się od początku, więc nie trzeba zwracać na to większej uwagi. Jeśli chodzi o tryb ‘r’ lub ‘r+’ to wewnętrzny wskaźnik ustawiany jest na początku pliku i przy zapisie danych jest on mało wygodny. Ma jednak duże znaczenie przy odczycie danych, gdyż nie musimy w tym celu cofać na sam początek. Jeśli chodzi o trzeci tryb ‘a’ lub ‘a+’ to wewnętrzny wskaźnik ustawiany jest na końcu pliku. Ma to w większości wypadków zastosowanie w zapisie danych. Nie musimy w tym celu przechodzić wiersz po wierszu na koniec pliku tylko bezpośrednio wstawiamy dane.
Teraz powyższe zastosowania przedstawię na przykładach. Pierwszy będzie tryb ‘w’ (‘w+’):
$plik = fopen(‘dane.txt’, ‘w’); fwrite($plik, ‘Pierwszy wpis do pliku!’); // zapisuje dane do pliku fclose($plik); |
W ten sposób zapisałem tekst ‘Pierwszy wpis do pliku!’ do nowo utworzonego pliku. Teraz za pomocą trybu ‘r+’ otworze pobiorę te dane i przypisze je do zmiennej, a następnie wypisze na ekranie.
$plik = fopen(‘dane.txt’, ‘r+’); $wiersz = fread($plik, 1024); // pobiera cały pierwszy wiersz pliku i przypisuje zmiennej fclose($plik); print “Zawartość wiersza to: <b>$wiersz</b>”; |
Teraz, żeby uzasadnić działanie trybu ‘a+’ przypisze do tego pliku jeszcze jedne wiersz najpierw za pomocą trybu ‘r+’, a następnie ‘a+’:
Tryb ‘r+’:
$plik = fopen(‘dane.txt’, ‘r+’); fseek($plik, 0, SEEK_END); fwrite($plik, ‘Drugi wpis do pliku!’); // zapisuje dane do pliku fclose($plik); |
Zastosowałem tutaj nie znaną Ci jeszcze z działania funkcję fseek(), która przesuwa wewnętrzny wskaźnik pliku o podaną jako drugi parametr ilość pozycji. Ja zastosowałem tutaj dodatkowy (opcjonalny) parametr, który ustawił wewnętrzny wskaźnik na końcu pliku – więcej o tej funkcji poczytaj w dokumentacji PHP.
Teraz to samo mogę zadanie przedstawię w trybie ‘a+’:
$plik = fopen(‘dane.txt’, ‘a+’); fwrite($plik, ‘Drugi wpis do pliku!’); // zapisuje dane do pliku fclose($plik); |
Dzięki tak zastosowanej metodzie skrypt działa szybciej, a co najważniejsze zmniejsza objętość kodu i wykonuje zadane polecenie.
3.Blokowanie dostępu do pliku podczas pobierania lub zapisu danych:
Zapewne zwróciłeś uwagę na to, że jednoczesne zapisywanie danych przez kilka osób do jednego pliku może spowodować błędy w danych. PHP posiada jednak funkcję, która rozwiązuje ten problem. Jest to funkcja flock(); Umożliwia ona na chwilowe zablokowanie dostępu do pliku podczas, gdy jeden z użytkowników właśnie dodaje lub pobiera informacje. Jest to bardzo przydatne i należy zawsze stosować tą funkcje. Wyjątkiem jest brak dostępu do tej funkcji na serwerze. Przykładem zastosowania tej funkcji jest taki krótki skrypt:
$plik = fopen(‘dane.txt’, ‘a+’); flock($plik, 1); // blokuje na czas użytkowania dostęp do pliku fwrite($plik, ‘Drugi wpis do pliku!’); // zapisuje dane do pliku fclose($plik); |
Więcej o tej funkcji możesz poczytać w dokumentacji PHP.
4. Dodatkowe przydatne funkcje
Załóżmy, że potrzebujesz przeanalizować dane w pliku znak po znaku. Do tego celu potrzebujesz funkcje, która pobierała by po jednym znaku z pliku, aż do osiągnięcia jego końca. Metoda ta jest rzadko stosowana, ale znalazła swe zastosowanie w wieli poważnych skryptach – może posłużyć, np. do odczytywania hasła pobierając co trzeci znak z wiersza. Owszem, ten sam efekt możemy osiągnąć poprzez stosowanie funkcji fgets(), ale nie zawsze znajduje to zastosowanie. Funkcją, która spełnia wymienione warunki to fgetc(). Jej działanie przeanalizuje na podstawie krótkiego skryptu:
$plik_dane = ‘dane.txt’; // przypisanie adresu pliku do zmiennej $plik = fopen($plik_dane, ‘w’); fwrite($plik, ‘abcdefghijk’); // wpisanie danych do pliku fclose($plik); $plik = fopen($plik_dane, ‘r+’); $i = 1; while(!feof($plik)) { $litera = fgetc($plik); print “Litera nr $i to <b>$litera</b><br>”; } fclose($plik); |
W ten sposób dane z pliku pobierałem znak po znaku, aż do osiągnięcia końca pliku. Na pewno zwróciłeś uwagę na zastosowaną tu funkcje feof(). Zwraca ona wartość ‘true’ kiedy osiągnięto koniec pliku i ‘false’ w przeciwnym przypadku. Znajduje ona także zastosowanie w pobieraniu danych funkcją fgets(), gdyż przeważnie nie wiemy ile jest wierszy w danym pliku.
Jeszcze dwiema wartymi zwrócenia uwagi funkcjami są ftell() i rewind(). Są bardzo przydatne przy poruszaniu się wewnątrz pliku. Pierwsza z nich zwraca położenie wewnętrznego wskaźnika pliku co umożliwia poruszanie się wewnątrz pliku bez narażenia zawartych w nim danych na uszkodzenie. Druga z nich służy do ‘przewijanie pliku’, czyli na przesunięcie wewnętrznego wskaźnika pliku na początek. Dzięki temu możemy bez problemu wielokrotnie przetwarzać dane na raz otwartym pliku. Oczywiście kiedy zmienimy jego zawartość, dobrym zwyczajem jest zamknięcie pliku i ponowne jego otwarcie do kolejnego przetwarzania informacji.
Skoro zapoznałeś się z działaniem podstawowych funkcji, dzięki którym możemy operować danymi zawartymi w plikach, to teraz na zakończenie działu napiszę prosty w wykonaniu skrypt zliczający liczbę odwiedzin na stronie.
5. Licznik odwiedzin
Otwórz dowolny edytor tekstowy i zapisz nowy dokument jako ‘licznik.php’. Teraz zapisz w nim poniższy kod:
<? $dane = ‘dane.txt’; // plik, w którym będą przechowywane dane if (file_exists($dane)) { $plik = fopen($dane, ‘r+’); // otwieramy plik flock($plik, 1); // nakładamy blokadę na dostęp do pliku $licznik = (int) fgets($plik, 1024); // pobieramy dane z pliku fclose($plik); // zamykamy plik $licznik++; // zwiększamy wartość licznika o 1 $plik = fopen($dane, ‘w+’); // nadpisujmy plik – w ten sposób go czyścimy flock($plik, $licznik); // nakładamy blokadę na dostęp do pliku fwrite($plik, 1); // wpisujemy nową wartość licznika fclose($plik); // zamykamy plik } else { $licznik = 1; // wstawiamy wartość licznika równą 1 $plik = fopen($dane, ‘w+’); // tworzymy nowy plik flock($plik, $licznik); // nakładamy blokadę na dostęp do pliku fwrite($plik, 1); // wpisujemy wartość licznika fclose($plik); // zamykamy plik } print “Obecnie stronę odwiedziło <b>$licznik</b> osób! ”; ?> |
Teraz na dowolnej stronie – z rozszerzeniem .php lub .php3 – zastosuj taką konstrukcje:
<? include(‘licznik.php’); ?> |
Pamiętaj, że aby ta konstrukcja była poprawna podany plik powinien znajdować się w tym samym katalogu co plik z licznikiem.