12. Operacje na plikach
Transkrypt
12. Operacje na plikach
KURS PHP 12. OPERACJE NA PLIKACH PHP, jako język skryptowy moŜe wykonywać się po stronie serwera, w tym takŜe wykonywać operację na plikach. W lekcji z pętlami mieliśmy juŜ przypadek pobrania z pliku odpowiednich informacji, ale to było absolutną podstawą. Teraz poznamy prawdziwą zabawę z tym językiem. Uwaga: PHP jest językiem doskonale integrującym się z bazami danych, w których znacznie lepiej i łatwiej jest przechowywać dane, ale do istnienia baz danych potrzebny jest serwer, który takim czymś dysponuje, ale... kurs nie jest poświęcony językom baz danych (SQL). Uwaga: plik, na którym działa skrypt PHP musi mieć odpowiednie przywileje. Jest to tzw. CHMOD – Chalenge Mode (ang. zmiana trybu). Korzystając z klienta FTP moŜemy łatwo to zmienić. Aby wartość pliku moŜna było edytować naleŜy uŜyć CHMODu o wartości 666, aby móc go skasować, takŜe edytować naleŜy uŜyć CHMODu o wartości 777, a aby plik odczytać wystarczy CHMOD 644, który zwykle jest domyślny dla wysyłanych plików. Na serwerach postawionych na systemie Windows nie musimy martwić się o CHMOD. fopen() i rodzaje uprawnień Wszystkie funkcje, które dotyczą działań na plikach poprzedzone są literką f, co oznacza skrót od słowa file (ang. plik). Pierwszą poznaną funkcją będzie fopen() (ang. otwórz plik), która zawiera dwa argumenty. JeŜeli jeszcze o tym nie wspominałem, a na pewno wspominałem argumenty oddzielamy przecinkami. Pierwszy argument przechowuje ścieŜkę dostępu do otwieranego pliku, a drugi, co ma z nim zrobić (tzw. tryb). Głównymi trybami są: • a - do dopisywania treści do treści juŜ istniejącej (na samym końcu pliku) (666) • r - do odczytywania treści bez jej modyfikacji (644) • w - do dopisywania treści uprzednio usuwając istniejącą zawartość pliku (666) www.INFORMATYKA.cba.pl KURS PHP Mniej waŜnymi, ale godnymi uznania są tryby rozszerzające tryby juŜ istniejące poprzez dodania plusika. Są to: • a+ - do dopisywania treści do treści juŜ istniejącej (na samym końcu pliku) plus moŜliwość odczytania jej (całości pliku) – wskaźnik na końcu pliku (666) • r+ - do odczytywania treści plus moŜliwość do dopisywania treści do treści juŜ istniejącej (na samym końcu pliku) • w+ - do dopisywania treści uprzednio usuwając istniejącą zawartość pliku plus moŜliwość odczytania jej – wskaźnik na końcu pliku (666) Uwaga: liczby w nawiasach oznaczają minimalny CHMOD, wymagany do wykonania danej operacji. Uwaga: w przypadku braku pliku, którego chcemy modyfikować [za pomocą trybów: w(+) i a(+)], jeŜeli jest taka moŜliwość plik zostanie stworzony. Nie stanie się to jednak w przypadku trybu r+, gdyŜ przed zapisem plik jest odczytywany. Odczytywanie zawartości pliku Istnieje kilka funkcji pozwalających na odczytywanie treści z plików, są to: • fgetc() - funkcja pobiera pierwszy znak z pliku • fgets() - funkcja pobiera pierwszą linię z pliku • fread() - czyta ustalony ciąg znaków Stwórzmy teraz plik o przykładowej nazwie plik.txt i umieśćmy w nim kilka byle jakich znaków np. asdF. Uwaga: rozszerzenie nie ma znaczenia, moŜe być to nawet rozszerzenie nie istniejące, ogólny brak rozszerzenia, czy nawet takie rozszerzenia jak php, czy php3. Uwaga: jeŜeli do tej pory wszystko testowaliśmy na serwerze zdalnym, na 99% musimy zmienić CHMOD na 666 (to takŜe pozwala na odczyt), z wykluczeniem serwerów postawionych na oprogramowaniu Microsoft. W bardzo łatwy sposób moŜemy odczytać literkę a, z ustalonej treści asdF. Funkcja fgetc ma w sobie tylko jeden argument – funkcję otwierającą plik i odpowiada za pobranie pierwszego znaku z pliku: www.INFORMATYKA.cba.pl KURS PHP <?php $plik = fopen("plik.txt","r"); $znak = fgetc($plik); echo $znak; fclose($plik); ?> W miejscu postawienia tego skryptu powinniśmy ujrzeć literkę a. Widzimy tutaj takŜe funkcję fclose(), pewnie znajomość angielskiego mówi nam, Ŝe to jest zamknięcie pliku... i dobrze nam mówi. Pozostawienie pliku otwartego moŜe spowodować róŜne niezgodności, w szczególności, jeŜeli jeden plik jest otwarty wielokrotnie np. przez odświeŜanie strony. Oczywiście jeden znak to za mało, aby mówić o czymś ciekawym, pobierzmy z niego całą linię, tzn. w naszym przypadku asdF (linia jest od początku do znaku przejścia do nowej linii): <?php $plik = fopen("plik.txt","r"); $linia = fgets($plik); echo $linia; fclose($plik); ?> Oczywiście linia to jest wciąŜ za mało, czas na czytanie większych objętości tekstu, w naszym pliku plik.txt stwórzmy nową linię, za pomocą klawisza Enter i umieśćmy w niej np. Qwerty. Za pomocą funkcji fread() moŜemy odczytać określoną ilość znaków (umieszczając określony argument w tej funkcji) np.: <?php $plik = fopen("plik.txt","r"); $czytaj = fread($plik,100); echo $czytaj; fclose($plik); ?> www.INFORMATYKA.cba.pl KURS PHP Sprawdzanie wielkości pliku - filesize() Skrypt ten jest odpowiedzialny za wyświetlenie pierwszych stu znaków (gdyŜ taka liczba została zadeklarowana) z danego pliku. Oczywiście nie polecam robić tak, jak jest w przykładzie – kaŜemy wyświetlać z niego więcej znaków niŜ jest w nim zapisanych. MoŜemy sobie znacznie ułatwić zadanie korzystając z funkcji filesize(), której argumentem jest nazwa pliku (ale nie nazwa zmiennej otwierająca plik). To takŜe najlepiej przypisać do jakiejś zmiennej. Funkcja filesize() zwróci nam rozmiar pliku w bajtach, a jak pewnie wiemy, a warto wiedzieć kaŜdy znak moŜliwy do łatwego zrozumienia przez człowieka zajmuje jeden bajt. Przykład zastosowania filesize(): <?php $plik = fopen("plik.txt","r"); $rozmiar = filesize("plik.txt"); $czytaj = fread($plik,$rozmiar); echo $czytaj; fclose($plik); ?> Uwaga: za pomocą tej funkcji moŜemy łatwo zautomatyzować dział download na naszej stronie, o ile taki istnieje. Za pomocą funkcji filesize() połączonej z instrukcjami warunkowymi moŜemy zapomnieć o mozolnym pisaniu rozmiarów dokumentów np.: <?php $nazwa = ""; // przypisujemy nazwę danego pliku $rozmiar = filesize("download/$nazwa"); if ($rozmiar >= 1048576) { $rozmiar = $rozmiar / 1048576; $rozmiar = round($rozmiar); $rozmiar = "$rozmiar MB"; } else if ($rozmiar >= 1024) { $rozmiar = $rozmiar / 1024; $rozmiar = round($rozmiar); $rozmiar = "$rozmiar kB"; } www.INFORMATYKA.cba.pl KURS PHP else { $rozmiar = "$rozmiar b"; } ?> Uwaga: pamiętajmy, Ŝe kaŜdy znak nowej linii zostanie zamieniony na zwykłą spację. Tak naprawdę na końcu kaŜdej linii odczytywanej przez PHP znajduje się niewidzialny dla nas, widoczny dla skryptu znak \n. MoŜna go za pomocą funkcji str_replace() zamienić na rozumny dla nas html-owe BR. Funkcja ta składa się z trzech argumentów – pierwszy to poszukiwany znak/fraza, drugi to zmiennik dla poszukiwanego znaku/frazy, trzeci to przewaŜnie nazwa zmiennej, z której ma być zmieniana treść: <?php $plik = fopen("plik.txt","r"); $rozmiar = filesize("plik.txt"); $czytaj = fread($plik,$rozmiar); $czytaj = str_replace("\n","<br />",$czytaj); echo $czytaj; fclose($plik); ?> Zapisywanie informacji w pliku - fwrite() Funkcje odczytu znamy aŜ nadto, rozszerzmy teraz ją, oczywiście za pomocą znaczka plus. Funkcja ta będzie pozwalała nam na odczyt i dodatkowo na zapis. Wyraziłem się dokładnie – dodatkowo, tzn. waŜniejszy jest odczyt i "rozbabrać" moŜemy dopiero plik po jego odczytaniu. Do zapisywania/dopisywania, czy w trybie r+, czy w, w+, a, czy a+ słuŜy ta sama funkcja fwrite() składająca się z dwóch argumentów – pierwszy zawiera otwierany plik w jednym z powyŜej wymienionych trybów, a drugi zawiera frazę, ewentualnie nazwę zmiennej, która przechowuje dopisywany ciąg znaków. Oto przykład funkcji fwrite() w trybie r+: www.INFORMATYKA.cba.pl KURS PHP <?php $plik = fopen("plik.txt","r+"); $linia = fgets($plik); fwrite($plik,"tekst"); echo $linia; fclose($plik); ?> Do naszego ciągu znaku, bez róŜnicy, czy było to asdF, czy Qwerty, czy coś innego powinniśmy dodatkowo ujrzeć wyraz tekst, oczywiście po odświeŜeniu, gdyŜ jest to zapisywane przed odczytaniem. A po odświeŜeniu oczywiście nie tylko zobaczymy tekst, ale w tle zostanie on zapisany po raz kolejny. Dwa tryby juŜ poznaliśmy. Teraz krótko omówmy sobie tryb w. Sam tryb odświeŜy nam plik – usunie z niego wszystko i moŜemy w nim zapisywać treść od nowa. Oto przykład zastosowania tego trybu: <?php $plik = fopen("plik.txt","w"); fwrite($plik,"tekst"); ?> Uwaga: zmian nie jesteśmy w stanie zaobserwować korzystając z tego skryptu, ale są one naprawdę rejestrowane. MoŜemy się upewnić otwierając plik – ujrzymy tam napis tekst, a w przypadku zmiany drugiego argumentu w funkcji fwrite() ujrzymy inny ciąg znaków. Tryb w+ umoŜliwia nam odczytanie tego, co zostało na nowo zapisane w pliku tekstowym. W przykładowym kodzie, który zaraz pojawi się ujrzymy nową funkcję - fseek(), która jest odpowiedzialna za umieszczenie wskaźnika. Zawiera dwa argumenty, najczęściej zmienną z otwieranym plikiem i obowiązkowo cyfrę oznaczającą pozycję wskaźnika wyraŜoną w liczbie, którą najczęściej jest zero. Przykład zastosowania trybu w+: <?php $plik = fopen("plik.txt","w+"); fwrite($plik,"tekst"); fseek($plik,0); $linia = fgets($plik); echo $linia; fclose($plik); ?> www.INFORMATYKA.cba.pl KURS PHP Uwaga: tutaj teŜ poprzez odświeŜanie moŜemy uwaŜać, Ŝe zmiana nie została wprowadzona, ale zmieniając odpowiedni argument funkcji fwrite() wszystko się wyjaśni. Uwaga: funkcji fseek moŜemy uŜywać w wielu przypadkach, nie tylko w danym trybie, takŜe w innych trybach zapisująco-odczytujących, a takŜe i w samych odczytujących. TakŜe za pomocą tej funkcji moŜemy czytać z następnych linijek. Tryb a pozwala na dopisywanie treści do pliku juŜ istniejącego. Kod jest podobny do kodu dla trybu w, na którym się wzorowałem, jednakŜe ten tryb nie traktuje tak drastycznie wpisanych juŜ znaków np.: <?php $plik = fopen("plik.txt","a"); fwrite($plik,"tekst"); fclose($plik); ?> Tryb a+ jest podobny do trybu r+, jednakŜe w przeciwieństwie do r+ zmiany widzimy natychmiast: <?php $plik = fopen("plik.txt","a+"); fwrite($plik,"tekst"); fseek($plik,0); $linia = fgets($plik); echo $linia; fclose($plik); ?> Uwaga: bardzo częstym błędem młodych programistów jest zapominanie o funkcji pozwalającej na przemieszczenie pozycji kursora – funkcji fseek(). Uwaga: większość trybów została przedstawiona za pomocą wyświetlania danej linijki, oczywiście moŜemy takŜe uŜyć innych poznanych z tej lekcji funkcji odczytujących. www.INFORMATYKA.cba.pl KURS PHP Oto prosty skrypt pozwalający bardziej ciekawie dopisać coś do bazy danych: <?php if ($_POST[fraza] == TRUE) { $plik = fopen("plik.txt","a+"); fwrite($plik,$_POST[fraza]); fseek($plik,0); $linia = fgets($plik); echo "Zawartość danego pliku to <PRE>$linia</PRE>"; fclose($plik); } else { echo "<FORM ACTION=\"index.php\" METHOD=\"post\"> Wpisz coś, co zostanie zapisane w pliku:<br /> <INPUT TYPE=\"tekst\" NAME=\"fraza\"><br /> <INPUT TYPE=\"submit\" VALUE=\"Dodaj to!\"> </FORM>"; } ?> Bezpieczne modyfikowanie plików, blokowanie: flock() Przechowywanie danych w plikach naraŜa nas na pewne niebezpieczeństwo. Wyobraźmy sobie sytuację, Ŝe jednocześnie na stronę wchodzą dwie osoby. Na danej stronie znajduje się licznik odsłon. Sytuacja jest taka, Ŝe dwie osoby mają identyczne łącza, bez Ŝadnych przeciąŜeń itp. Serwer naraz otwiera dwa pliki, podwyŜsza liczbę naraz je zamyka. MoŜe wywołać to całkiem spore błędy – licznik moŜe zapisać zupełnie inną liczbę, albo nawet zamiast cyfr wyświetlić tekst :). śeby uniknąć takich sytuacji stosujemy funkcję flock() (ang. plik zablokuj). Składa się ona z dwóch argumentów, z których pierwszym jest otwierany plik, a drugi moŜe mieć wartość: • 1 - moŜliwy tylko odczyt • 2 - moŜliwy tylko zapis • 3- odblokowanie pliku www.INFORMATYKA.cba.pl KURS PHP Przykładowy skrypt z zastosowaniem blokowania to: <?php $plik = fopen("plik.txt","a+"); flock($plik,2); fwrite($plik,"tekst"); flock($plik,3); flock($plik,1); fseek($plik,0); $linia = fgets($plik); flock($plik,3); echo $linia; fclose($plik); ?> Teraz juŜ nie musimy martwić się o jakiekolwiek błędy w naszych skryptach. Nadawanie CHMODów za pomocą PHP Na koniec długiej lekcji słówko o CHMODach. MoŜemy je ustawiać za pomocą klienta FTP, aczkolwiek nie tylko. Za pomocą funkcji chmod(), w której pierwszym argumentem będzie lokalizacja do pliku, a drugim określony CHMOD poprzedzony zerem moŜemy te parametry zmieniać. Dla przykładu, chcemy przestawić CHMOD naszego pliku plik.txt na np.: 666 (jeŜeli plik ma takie atrybuty, zmieńmy je na chwilę, aby zaobserwować zmiany): <?php chmod("plik.txt",0666); ?> www.INFORMATYKA.cba.pl