Lekcje >> Podstawy PHP
Polimax

Drukarnia w Warszawie realizująca druk wizytówek, plakatów jak również fotoksiążki, fotoobrazy i fotokalendarze - z wysyłką na terenie całego kraju.

Zapis danych

Otwieranie pliku

Jak już powiedzieliśmy, aby wykonać jakiekolwiek operacje na pliku, najpierw należy ten plik otworzyć. Służy do tego funkcja fopen(ścieżka dostępu do pliku, tryb otwarcia). Najlepiej posługiwać się ścieżkami względnymi co zostało omówione w podstawach HTML. Istnieje kilka trybów otwarcia pliku, my będziemy stosować dwa:

  • w - otwarcie pliku do zapisu, jeżeli plik istnieje, to jego zawartość zostanie usunięta i zapisane będą aktualne dane, jeżeli plik nie istnieje, podjęta będzie próba jego utworzenia;
  • r - otwarcie pliku do odczytu, dane odczytywane są od początku pliku.

Należy zdawać sobie sprawę z tego, że próba otwarcia pliku może zakończyć się niepowodzeniem, spowodowanym np. brakiem odpowiednich uprawnień użytkownika. Funkcja fopen(), zwróci wtedy false i co gorsze zostanie pokazany komunikat o błędzie. Aby uniknąć straszenia użytkownika komunikatami, najczęściej przez niego niezrozumiałymi, należy zastosować operator tłumienia błędów - @.

Blokowanie pliku

Co będzie, jeżeli kilku użytkowników zechce zapisać dane w tym samym pliku w tym samym czasie? Na pewno nic dobrego z tego nie wyniknie. Istnieje prosty sposób zablokowania pliku dla innych użytkowników w czasie kiedy zapisujemy/odczytujemy dane. Po otwarciu pliku ale przed zapisem/odczytem danych należy zastosować funkcję flock(). Argumentami tej funkcji są wskaźnik do pliku (pokażemy to w ćwiczeniu) oraz paremetr określający rodzaj działania i przyjmujący następujące wartości:

  • LOCK_SH - blokowanie odczytu. Pozwala na dzielenie pliku z innymi czytającymi.
  • LOCK_EX - blokowanie zapisu. Plik wyłączony jest z użytku, nie może być współdzielony z innymi użytkownikami.
  • LOCK_UN - zwolnienie istniejącej blokady.

Funkcja flock() zwróci true, jeżeli blokada została prawidłowo założona, w przeciwnym wypadku, zwróci false.

Zapisywanie danych w pliku

Będziemy wykonywać za pomocą funkcji fwrite($wskaznik_pliku,$string_do_zapisania).

Zamykanie pliku

Jak już powiedzieliśmy, po wykonać jakichkolwiek operacji na pliku należy go obowiązkowo zamknąć. Wykonuje się to za pomocą funkcji fclose() zwracającej true w przypadku powodzenia operacji lub false po niepowodzeniu. Niepowodzenie zamknięcia jest mało prawdopodobne i raczej tego faktu się nie sprawdza.

Ćwiczenie 4_1_0_1. Zapisywanie danych w pliku

Zadanie polega na uwtorzeniu formularza, w którym użytkownik wpisze swoje nazwisko, rok urodzenia oraz miejsce zamieszkania, skrypt odbierający te dane zapisze je w pliku dane_osobowe.txt, znajdującym się w tym samym katalogu co pliki formularz.html oraz wyniki.php. Operacja powinna zakończyć się informacją o sukcesie lub niepowodzeniu.

Plik HTML:

<body>
  <form action="wyniki.php" method="post">
    Nazwisko<input type="text" name="nazwisko" />
    Rok urodzenia<input type="text" name="rok_urodzenia" />
    Miejsce zamieszkania<input type="text" name="miejsce_zamieszkania" />
    <input type="submit" name="submit"  value="Wyślij i zapisz w pliku" />
  </form>
</body>

Plik ze skryptem PHP:

<body>
  <?php
    $nazwisko=$_POST['nazwisko'];//1
    $rok_urodzenia=$_POST['rok_urodzenia'];//2
    $miejsce_zamieszkania=$_POST['miejsce_zamieszkania'];//3
    $do_zapisania=$nazwisko.' '.$rok_urodzenia.' '.$miejsce_zamieszkania;//4
    
    @$plik=fopen('dane_osobowe.txt','w');//5 
    if (!$plik)//6 
    {
      echo 'Wystąpił błąd podczas otwierania pliku!';//7
      exit;//8
    }
    
    if (!flock($plik, LOCK_EX))//9
    {
      echo 'Wystąpił błąd podczas zakładania blokady pliku!';//10
      fclose($plik);//11
      exit;//12
    }
    
    fwrite($plik,$do_zapisania);//13
    flock($plik, LOCK_UN);//14
    fclose($plik);//15
    echo 'Operacja zapisywania danych zakończona sukcesem!';//16
  ?> 
</body>

Komentarz skryptu PHP:

  1. Odbieramy nazwisko i przypisujemy zmiennej $nazwisko.
  2. Odbieramy rok urodzenia i przypisujemy zmiennej $rok_urodzenia.
  3. Odbieramy miejsce zamieszkania i przypisujemy zmiennej $miejsce_zamieszkania.
  4. Zmienna $do_zapisania jest łańcuchem, który zapiszemy w pliku.
  5. Otwieramy plik dane_osobowe.txt do zapisu (parametr w). Stosujemy tłumienie błędów za pomocą operatora @, aby uniknąć niepotrzebnych komunikatów. Wskaźnik do pliku $plik zastosujemy dalej do operacji na pliku.
  6. Jeżeli operacja otwierania pliku nie powiodła się...
  7. Wyświetlamy komunikat o niepowodzeniu.
  8. Kończymy skrypt.
  9. Zakładamy blokadę zapisu.
  10. Zamykamy plik, jeżeli jego blokada sie nie powiodła.
  11. Wyświetlamy komunikat o niepowodzeniu blokady.
  12. Kończymy skrypt.
  13. Zapisujemy łańcuch $do_zapisania w pliku dane_osobowe.txt.
  14. Odblokowujemy plik.
  15. Zamykamy plik.
  16. Wyświetlamy komunikat o sukcesie operacji zapisywania danych.

Ćwiczenie 4_1_0_2. Zapisywanie w pliku nazwy użytkownika i hasła

Zacznijmy od tego, że najbezpieczniej zapisać te dane w bazie danych. Jeżeli w pliku, to powinniśmy zapisać plik poza drzewem katalogów. Jeżeli nasz plik nazywa się pass.txt, to powinniśmy zastosować ścieżkę $_SERVER['DOCUMENT_ROOT']/../nasze_dane/pass.txt. Wbudowana w PHP zmienna $_SERVER['DOCUMENT_ROOT'] wskazuje podstawowy element drzewa katalogów serwera WWW. W katalogu nasze_dane powinniśmy umieścić plik .htaccess zawierający następujące instrukcje dla serwera:
Options -Indexes
Deny from all

Pierwszy wiersz zabrania indeksowania zawartości katalogu i pokazywania go w oknie przeglądarki, natomiast drugi blokuje dostęp do wszystkich plików i podkatalogów naszego katalogu. Dostęp będą miały tylko nasze skrypty. W naszym ćwiczeniu, dla uproszczenia, umieścimy plik pass.txt w tym samym katalogu co plik z formularzem. Zastosujemy jednostronne kodowanie naszych danych. Takie rozwiązanie dla danych które nie wymagaja szczególnej ochrony, jest wystarczające. Do szyfrowania zastosujemy funkcję md5(). Szyfrowanie jednostronne tutaj stosowane polega na tym, że nie nie jest możliwe odtworzenia tekstu szyfrowanego na podstawie tekstu zaszyfrowanego. Jak więc to działa? Użytkownik logując się, musi podać właściwe hasło, skrypt zaszyfruje je i sprawdzi, czy postać zaszyfrowana jest identyczna z tekstem zapisanym.

W tym ćwiczeniu jedynie zapiszemy nasz login i hasło, wrócimy jeszcze do tego podczas tworzenia skryptu logowania się użytkownika na stronie. Zapisz więc te dane w zeszycie, bo jak powiedzieliśmy wcześniej - na podstawie danych zaszyfrowanych nie można odtworzyć danych oryginalnych.

Plik HTML:

<body>
  <form action="wyniki.php" method="post">
    Login<input type="text" name="login" />
    Hasło<input type="password" name="haslo" />
    <input type="submit" name="submit"  value="Zapisz w pliku" />
  </form>
</body>

Plik ze skryptem PHP:

<body>
  <?php
    $login=$_POST['login'];
    $haslo=$_POST['haslo'];
    $do_zapisania=md5($login).' '.md5($haslo);
    
    @$plik=fopen('pass.txt','w');
    if (!$plik)
    {
      echo 'Wystąpił błąd podczas otwierania pliku!';//7
      exit;
    }
    
    if (!flock($plik, LOCK_EX))
    {
      echo 'Wystąpił błąd podczas zakładania blokady pliku!';
      fclose($plik);
      exit;
    }
    
    fwrite($plik,$do_zapisania);
    flock($plik, LOCK_UN);
    fclose($plik);
    echo 'Operacja zapisywania danych zakończona sukcesem!';
  ?> 
</body>

Powyższe kody nie wymagają komentarza, nie wykonujemy tu niczego co nie zostało wcześniej omówione.


Jeżeli zapomniałeś jak przygotować i gdzie zapisywać pliki testowe: