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