MOJA PASJA - PROGRAMOWANIE
   Dzisiaj jest Poniedziałek, 1 maja, 2017r. Ostatnia aktualzacja miała miejsce: 10 grudnia 2006r. Homepage

Programowanie: Artykuły * FAQ * Download * Komponenty * Książki WWW: Artykuły * Narzędzia * Kursy * Darmowe * FAQ * Skrypty * Ksiązki Off-Topic: Aforyzmy * Humor Inne: Forum * Wiki * Liczniki * Linki * Chat * Grafika * Video * Inne



Obsługa plików w PHP


   Bez znajomości obsługi plików w PHP ciężko napisać jakiś przyzwoity skrypt. Jest to podstawowa forma przechowywania danych. Oczywiście można skorzystać z MySQLa, ale po pierwsze, MySQLa raczej nie znajdziesz na darmowych serwerach www z obsługą PHP, a po drugie, nawet jeżeli posiadasz już komercyjny serwer, przestrzeń w bazie MySQL jest o wiele droższa od przestrzeni dyskowej. Do rzeczy.

Operacje na plikach

Na początek opiszę jak dobrać się do pliku, dopiero później przeanalizujemy sposoby przechowywania w nim danych.

No to otwieramy

Zanim zaczniemy coś zapisywać, bądź też odczytywać z pliku, musimy go najpierw otworzyć, oraz skojarzyć z jakąś zmienną z której będziemy później korzystać przy odwoływaniu się do niego. W podanych tu przykładach będzie to zmienna $plik (ambitna nazwa, no nie ? ;)). Do otwarcia pliku służy funkcja fopen(). Posiada dwa argumenty. Pierwszy to nazwa pliku, natomiast drugi, to tryb w jakim plik ma być otworzony. To co funkcja zwraca przypisujemy do naszej zmiennej $plik. Czyli np.

$plik = fopen("pliczek.txt","w+");


   Teraz troszkę o drugim parametrze, może on przyjmować następujące wartości:

aOtwiera plik do dopisywania danych. Dane będą dodawane na końcu pliku
a+Otwiera plik do oczytu i dopisywania danych. Dane będą dodawane do końca pliku
rOtwiera plik tylko do odczytu (również plików za pomocą protokołu HTTP)
r+Otwiera plik do odczytu i zapisu. Dane będą dodawane na początku pliku
wOtwiera plik tylko do zapisu. Jeżeli plik istnieje wszystkie dane zostaną skasowane, jeżeli nie, PHP spróbuje go utworzyć
w+Otwiera plik do odczytu i zapisu. Jeżeli plik istnieje wszystkie dane zostaną skasowane, jeżeli nie, PHP spróbuje go utworzyć


Jeżeli otwieramy plik do odczytu, dopuszczalne jest także podanie adresu HTTP (chyba że jest to zablokowane na serwerze). Czyli możemy np napisać:

$plik = fopen("http://www.example.com/", "r");


Odczytujemy ...

   Jeżeli mamy już otworzony plik możemy coś odczytać np. dwuargumentową funkcją fread(). Pierwszy argument to nasza zmienna skojarzona z plikiem, natomiast drugi to liczba bajtów które chcemy odczytać. Funkcja zwraca to, co odczytała. Przykład:

$tresc = fread($plik, filesize('pliczek.txt'));


Cała zawartość pliku znajdzie się w zmiennej $tresc.

$tresc = fread($plik, 100);


W zmiennej znajdziemy pierwsze 100 znaków pliku.

Nie jest to jednak jedyna funkcja do odczytywania zawartości plików możemy jeszcze korzystać z:

fpassthru()Wywala całą zawarość pliku na ekran, Użycie:
fpassthru($plik);

fgets()Działa tak samo jak fread, ale ma haczyk. Pobiera o jeden bajt mniej niż podasz jej w drugim argumencie. W przypadku gdy drugi argument nie jest podany automatycznie pobiera 1024 bajty, jeżeli ma on wartość większą od długości pliku pobietany jest cały plik.
$tresc = fgets($plik,101);

fgetss()Działa tak samo jak fgets, ale wycina wszyskie napotkane kody PHP i HTML.
$tresc = fgetss($plik,71);



   Jest jeszce jeden bardzo ładny sposób na odczytywanie plików ale o nim za chwilę.

... i zapisujemy

   Bo nie będziemy mieli co czytać ;) Przy zapisie należy pamiętać, że skrypt musi mieć odpowiednie prawa do zapisu, ewentualnie utworzenia pliku. Jeżeli zamierzamy edytować pojedyńczy plik najłatwiej nadać mu uprawnienia następującą komendą ftp:

CHMOD 666 pliczek.txt


   Jeżeli mamy klikalnego klienta ftp komnedę chmod zazwyczaj wywołuje się gdzieś z menu które pokaże się po kliknięciu prawym przyciskiem myszy na pliku. Jeżeli zamierzamy tworzyć nowe pliki, katalogowi w którym zamierzamy je tworzyć nadajemy w ten sam sposób prawa zapisu, jednak zamiast atrybutów 666 przypisujemy 777.

   Do zapisu korzystamy z funkcji fputs() lub fwrite() (pierwsza jest aliasem tej drugiej). Pierwszy argument to nasza ukochana zmienna do której przypisany jest plik, natomiast drugim jest oczywiście to, co chcemy zapisać:

fputs($plik,"A kot ma już dość Ali\n");


   Dla niewtajemniczonych dodam, że \n jest znakiem przejścia do następnej linii.

Zamykamy

Jak już się nacieszymy pracą z plikiem możemy go zamknąć:

fclose($plik);


Przykład

Jak widać, mimo że napisałem to w bardzo rozlazły sposób operacje na plikach nie są trudne. Podam może jeszce gotowy przykład zapisu (lub utworzenia w przypadku gdy nie istnieje) do pliku pliczek.txt:

$plik = fopen("pliczek.txt","w+");
fputs($plik,"Life is a bitch, and so am I\n");
fclose();


I odczyt:

$plik = fopen("pliczek.txt","r");
fpassthru($plik);


Tak, nie ma wywyołania funkcji fclose(). A to dlatego, że fpassthru() wywołuje ją automatycznie.

Odczyt inaczej

A teraz jeszcze jeden sposób na odczyt z pliku. Osobiście korzystam tylko z niego. Jest to bardzo prosta funkcja file(). Jako argument podajemy ścieżkę do pliku, a zwraca nam... tablicę, w której pojedyńcze elementy odpowiadają linijkom pliku.

$tablica = file("pliczek.txt");
for ($i=0; $i<count($tablica); $i++)
{
  echo "Linijka $i: ".$tablica[$i]."<br>";
}


   Myślę, że ze zrozumieniem tego kodu nie powinno być problemu.

Przechowywanie danych

   A teraz praktyczne zastosowania operacji na plikach. Załóżmy, że mamy do przechowania tablicę użytkowników. Dla każdego użytkownika chcielibyśmy zapisać hasło, numer identyfikacyjny i jakiś opis. Jest wiele sposobów na zapisanie takich danych w plikach, ja osobiście zrobiłbym to tak (treść pliku):

1|comboy|jakieshaslo|A to jest mój opis|
2|luser|innehaslo|A to jest jego opis|
2|luserka|lusereczka|A to jest jej opis|


Itd. Jak widać struktura pliku bardzo przypomina graficzne odwzorowanie tablicy. W każdej linijce mamy po jednym wierszu tablicy. Funkcja file() błaga wręcz o jej zastosowanie. Po rozbiciu na linijki, każdą linijkę rozbijamy na kolumny, za pomocą funkcji explode. Jako pierwszy argument podajemy jej ciąg znaków którym oddzielone są od siebie kolumny, a jako drugi linijkę. W zamian otrzymujemy tablicę, której pojedyncze elementy są kolumnami z pliku. Przykładowy kod będzie więc wyglądał następująco:

$lista = file('users.txt');

foreach ($lista as $userek)
{
  $tuser = explode('|',$userek);
  echo '<br>Id użytkownika: '.$tuser[0];
  echo '<br>Login użytkownika: '.$tuser[1];
  echo '<br>Hasło użytkownika: '.$tuser[2];
  echo '<br>Opis użytkownika: '.$tuser[3];
}


Gotowe. Ale warto zwrócić uwagę na jeszcez jedną rzecz. Jeżeli użtykownik poda nam np. w swoim opisie znak "|" lub znak nowej linii, zepsuje całą strukturę pliku. Możemy więc te znaki po prostu wyciąć, lub zastąpić jakimiś innymi, których prawdopodobieństwo wystąpienia jest znikome. Problem ten znika jeżeli rozmiar każdego pola ograniczymy do jakiejś liczby znaków i tylko tyle będziemy odczytywać. Np. pierwsze 3 znaki to id, 10 znaków to login, kolejne 10 to hasło, następne 40 to opis a znak 41 rozpoczyna już kolejny rekord.

A teraz załóżmy że mamy do przechowania w pliku konfigurację skryptu. Oczywiście można stworzyć tablicę jak w powyższym przykładzie i odczytać z niej różne wartości, jednak zazwyczaj o wiele bardziej praktyczne okazuje się zapisanie pliku PHP z wartościami zmiennych. Przykładowy wygląd pliku:

<?
  $admin_pass = 'dupa';
  $script_name = 'Super skrypt v.7.3';
  $dir = '/home/users/comboy/scripts/ssrcipt/';
?>


No i jeszcze zapisanie takiego pliku coby była jasność:

$plik = fopen('config.inc.php','w+');
fputs($plik,"<?\n");
fputs($plik,"\$admin_pass = $admin_pass\n");
fputs($plik,"\$script_name = $script_name\n");
fputs($plik,"\$dir = $dir\n");
fputs($plik,"?>\n");
fclose($plik):


Przy założeniu, że w zmiennych o takich nazwach jak te w pliku konfiguracyjnym mamy zapisane dane które chcemy zapisać do pliku. Można również zapisywać konfigurację w plikach o strukturze ini. Więcej info pod adresem http://pl2.php.net/manual/en/function.parse-ini-file.php

A gdyby... ?

   Wyobraźmy sobie, że kilka osób wchodzi jednocześnie na naszą stronę. My natomiast napisaliśmy sobie w PHP skrypt statystyk, który każdą wizytę odnotowuje w pliku user.log. Zostanie odpalonych kilka kopii tego skryptu, i wszystkie będą próbowały zapisać coś do pliku. Co się stanie ? Z moich doświadczeń wynika, że zazwyczaj zostają utracone wszystkie dane które znajdowały się w pliku. A tego chyba byśmy nie chcieli. Z pomocą przychodzi nam blokowanie plików. Obsługuje je funkcja flock(). Powinniśmy ją zastosować we wszystykich skryptach które będą operowały na pliku.

Funkcja jako pierwszy argument przyjmuje uchwyt do pliku (czyli nasza zmienna $plik), natomiast z drugiego argumentu dowiaduje się co ma zrobić.

LOCK_SH (1)Jeżeli chcemy odczytywać z pliku
LOCK_EX (2)W przypadku zapisu do pliku
LOCK_UN (3)Zwolnienie blokady


Funkcja zwracając nam wartość typu bool (true/false) oznajmia czy udało jej się zablokować dany plik.

Przykład:

$plik = fopen("user.log", "w+");

if (flock($plik, LOCK_EX)) // blokujemy
{
  fwrite($plik, "blablabla\n"); // zapisujemy dane
  flock($plik, LOCK_UN); // zwalniamy blokade
} else
{
  echo "Nie powiodło się zablokowanie pliku !"; // Ups ;)
}

fclose($plik);


Inne operacje na plikach

   PHP oferuje bardzo wiele funkcji związanych z operacjami na plikach. W tabelce poniżej znajdują się te wg. mnie najbardziej użyteczne.

file_exists()Sprawdza czy plik do którego ścieżkę podajemy w argumencie istnieje. Przykład
if (file_exists('pliczek.txt'))
{
  echo "Plik istnieje";
}

filesize()Zwraca rozmiar pliku w bajtach. Jako argument podajemy ścieżkę do pliku.
echo 'Rozmiar pliku to ';
echo round(filesize('pliczek.txt)/1024);
echo ' kilobajtów';

is_writable()Funkcja zwraca wartość true w przypadku gdy skrypt ma uprawnienia do zapisywania pliku podanego w argumencie.
if (is_writable('pilczek.txt'))
  echo 'Można zapisywać';

mkdir()Tworzy katalog o podanej nazwie. Jako drugi argument możemy podać prawa dostępu.
$katalog = 'dane';
if (mkdir($katalog,0700))
  echo "Katalog $katalog został pomyślnie utworzony";

unlink()Kasuje plik o podanej nazwie<.br>
if (unlink('pliczek.txt'))
  echo 'pliczek został skasowany ;(';



Inną dość często spotykaną operacją jest wypisanie wszystkich plików z danego katalogu. Funkcja glob() zwraca nam w tablicy wszystkie pliki które pasuja do maski podanej jako argument. Przykładowy kod wypisujący wszystkie pliki .dat z katalogu data:

$lista = glob("data/*.dat");
foreach ($lista as $plik)
  echo "$plik<br>";

Bezpieczeństwo

Pozostaje jeszcze sprawa bezpieczeństwa. W końcu jeżeli mamy przechowywać w plikach hasła użytkowników to raczej nie chcemy by ktoś mógł je przeglądnąć wpisując w przeglądarce http://www.example.com/data/hasla.txt. Ja zazwyczaj na pliki z danymi tworzę osobny katalog i umieszczam w nim plik o nazwie .htaccess (dokładnie tak się musi nazywać, z kropką na początku) z treścią:

deny from all


Jeżeli teraz ktoś z zewnątrz będzie próbował się do niego dobrać otrzyma komunikat o błędzie 403 (dostęp zabroniony).

No i chyba wystarczy tego skrótu o plikach. Polecam strony manuala PHP dotyczące obsługi plików, między innymi:

http://pl2.php.net/manual/pl/function.fopen.php
http://pl2.php.net/manual/pl/function.flock.php
http://pl2.php.net/manual/pl/function.file.php
http://pl2.php.net/manual/pl/function.explode.php
http://pl2.php.net/manual/en/function.glob.php




   Wasze opinie:
   Średnia ocena: 4.32/10 (242 głosów)
   
   Liczba komentarzy: 46665 (pokaż wszystkie)Skomentuj !   


Autor: CichyData dodania: 2016-07-28
Ciekawy sposób opisywania.. z humorem, a zarazem można coś ciekawego się nauczyć. Mam dość czytania sztywnych wywodów na różnego rodzaju stronach i forach, gdzie to piszą przemądrzali programiści, którzy uważają, że wiedzą wszystko, a tak w rzeczywistości, to sami nie potrafią poprawnie zakodować strony.


Autor: Data dodania: 2015-03-26


Autor: programista Data dodania: 2015-03-26
filtruj dane albo ,dodaj dodatkowe pytanie w formularzu bo , na tą chwile mój ośmioletni syn piszę lepsze skrypty


Autor: BirneData dodania: 2012-11-24
Wcale nie jest napisane w rozlazly sposob... im bardziej opisowo i im wiecej ciekawych przypominajacych dygresji tym lepiej. Pozdro z internetu


Autor: ArekData dodania: 2012-09-21
Swietny artykul, wlasnie taikch szczegolowych i praktycznych tekstow potrzeba w sieci szkoda ze google slabo to klasyfikuje dzieki i pozdrowienia dla autora


Autor: yltqhxData dodania: 2012-09-21
n7vk4I dqetrhhbpuxt, [url=http://drmgkobeqwmf.com/]drmgkobeqwmf[/url], [link=http://tymwfvoqyupg.com/]tymwfvoqyupg[/link], http://nqoeuodeuwlr.com/


Autor: tacktnxvnyzData dodania: 2012-09-21
zGsZcN rmvkttogkycj, [url=http://ckpjgkyfdfqf.com/]ckpjgkyfdfqf[/url], [link=http://douyosemtvnx.com/]douyosemtvnx[/link], http://usnadxyrdquq.com/



Stronę przygotował: Kacper Cieśla (comboy). Wszelkie prawa zastrzeżone.
Reklama * Zgłoś błąd * Kontakt * Hosting * O stronie * Sponsoring
Czas generowania strony: 0.352s