PHP/System plików: Różnice pomiędzy wersjami

Usunięta treść Dodana treść
Piotr (dyskusja | edycje)
m Wycofano zmiany wprowadzone przez Wikipedystę:83.29.51.168 i przywrócono wersję ostatnio zmienioną przez Wikipedystę:Zyx.
Zyx (dyskusja | edycje)
rozbudowa
Linia 102:
 
Sens takiego kodu można streścić w prostym porównaniu: pakować się tylko po to, by się natychmiast rozpakować. Nie służy to niczemu, a konsumuje niezbędny czas. Aby przekonać się, jak mało wydajne jest takie rozwiązanie, spróbuj załadować tak plik tekstowy o wielkości megabajta, następnie powtórz to samo z wykorzystaniem ''file_get_contents()'' i porównaj wrażenia.
 
{{Infobox|Jeżeli pragniesz odczytywać pliki binarne, otwieraj je z parametrem ''rb'' zamiast ''r''.}}
 
=== Zapis danych ===
Zapis danych wygląda analogicznie do odczytu. Różne jest tylko miejsce docelowe danych. Sposób pierwszy polega na otwarciu pliku funkcją ''fopen()'' i skorzystaniu z ''fwrite()'' do dodania nowej zawartości. Plik otwieramy z parametrem ''w'' (nadpisujemy starą zawartość) lub ''a'' (dopisujemy coś do pliku). W przypadku operowania danymi binarnymi, dodajemy jeszcze literę ''b''.
 
<nowiki><?php
 
$f = fopen('./plik.txt', 'w');
fwrite($f, 'To jest nowa zawartosc pliku');
fclose($f);
 
?></nowiki>
 
Po uruchomieniu tego skryptu w ''plik.txt'' powinna pojawić nam się nowa zawartość. W przypadku pracy na systemie Linux/Unix sprawdź, czy PHP ma uprawnienia do edycji plików w twoim katalogu roboczym.
 
W PHP 5.0.0 pojawiła się funkcja ''file_put_contents()'', która upraszcza całą sprawę. Zwraca ona liczbę zapisanych do pliku bajtów i możemy wykorzystać to do kontroli, czy operacja dopisywania faktycznie się udała. Funkcja pobiera dwa parametry: nazwę pliku oraz tekst do wpisania i "firmowo" nie zniekształca danych binarnych.
 
<nowiki><?php
 
if(file_put_contents('./plik.txt', 'To jest nowa zawartosc pliku') != 0)
{
echo 'Udalo sie zapisac nowa zawartosc do pliku.';
}
 
?></nowiki>
 
Zadajmy sobie pytanie, co jeśli musimy dopisać dodatkową treść. Naturalnie ''file_put_contents()'' także to potrafi. Trzeba tylko skorzystać z trzeciego parametru, w którym możemy ustawiać flagi. ''FILE_APPEND'' jest tym, czego potrzebujemy.
 
<nowiki><?php
 
if(file_put_contents('./plik.txt', ' dopisana tresc', FILE_APPEND) != 0)
{
echo 'Udalo sie dodac zawartosc do pliku.';
}
 
?></nowiki>
 
Ten skrypt będzie już dopisywać dane do pliku, zamiast je nadpisywać.
 
=== Informacje o plikach ===
W wielu przypadkach przydaje się wiedza o tym, co w zasadzie w katalogach mamy. Możemy ją uzyskać, korzystając z rodziny funkcji udostępniających nam różne informacje o plikach. Wszystkie przyjmują za parametr nazwę pliku:
* ''is_file()'' - zwraca '''true''', jeśli obiekt jest plikiem.
* ''is_dir()'' - zwraca '''true''', jeśli obiekt jest katalogiem.
* ''is_readable()'' - zwraca '''true''', jeśli posiadamy prawa do odczytu zawartości obiektu.
* ''is_writeable()'' - zwraca '''true''', jeśli posiadamy prawa do zapisu do obiektu.
* ''file_exists()'' - zwraca '''true''', jeśli plik/katalog istnieje.
* ''fowner()'' - zwraca ID właściciela pliku.
* ''fgroup()'' - zwraca ID grupy, do której plik należy.
* ''fperms()'' - zwraca uprawnienia pliku.
* ''filesize()'' - zwraca wielkość pliku.
* ''filemtile()'' - zwraca czas ostatniej modyfikacji pliku lub '''false''', jeśli nie istnieje.
 
Przy korzystaniu z nich musimy pamiętać o wydajności. Odczyt wszelkich danych z dysku jest dość powolny, dlatego starajmy się jak najwięcej wycisnąć z pojedynczego wywołania funkcji. Oto przykład: załóżmy, że mamy plik ''A.txt'' i na jego podstawie generujemy ''B.txt'' zawsze, kiedy ulegnie on zmianie (taki kompilator). Musimy zatem napisać mechanizm sprawdzający, czy można uruchomić kompilację, czy też jest ona zbędna.
 
<nowiki><?php
 
if(!file_exists('A.txt'))
{
die('Plik A.txt nie istnieje!');
}
 
if(file_exists('B.txt'))
{
if(filemtime('B.txt') != filemtime('A.txt'))
{
echo 'Plik A.txt wymaga kompilacji.';
}
else
{
echo 'Można czytać z pliku B.txt';
}
}
else
{
echo 'Plik A.txt wymaga kompilacji';
}
 
?></nowiki>
 
Pozornie wszystko wygląda na poprawne - skrypt prawidłowo raportuje wszystkie sprawy. Jednak robi to zbyt wolno, gdyż przeciążyliśmy go dużą ilością odwołań do dysku twardego. Jeżeli uruchomimy go na witrynie z dużym ruchem, osiągnąłby gorsze wyniki wydajności, niż inne skrypty. Spróbujmy go nieco zmodyfikować. Czy naprawdę potrzebujemy funkcji ''file_exists()''? Okazuje się, że nie. Przecież ''filemtime()'' zwróci nam '''false''', jeżeli plik nie będzie istniał i możemy to wykorzystać. Oto poprawiony kod skryptu:
 
<nowiki><?php
 
$czasA = @filemtime('A.txt');
if($czasA === false)
{
die('Plik A.txt nie istnieje!');
}
else
{
$czasB = @filemtime('B.txt');
}
 
if($czasB !== false)
{
if($czasB != $czasA)
{
echo 'Plik A.txt wymaga kompilacji.';
}
else
{
echo 'Można czytać z pliku B.txt';
}
}
else
{
echo 'Plik A.txt wymaga kompilacji';
}
 
?></nowiki>
Zauważmy, w tym przypadku mamy tylko dwa odwołania do dysku, a jeśli plik ''A.txt'' nie będzie istnieć, to nawet jedno! Zamiast wykonywania za każdym razem setek nowych funkcji, wykorzystujemy maksymalnie te dane, które już mamy. To jest właściwa filozofia przy pracy z plikami.
 
=== Zawartość katalogów ===