Cookies kontra sesje w PHP

Autor: Łukasz Świerżewski, dodano: 06-09-2003
Kategoria: Programowanie i tworzenie

Cookies i sesje to bardzo często stosowane elementy języka PHP, które pomagają przechowywać dane podczas wizyty użytkownika na stronie, a także po zakończeniu takiej wizyty. Dzięki nim działają systemów logowania, liczniki itp.

Cookie to nazwa wzięta z angielskiego - cookie - ciasteczko. Nazwa ta może być nieco myląca, gdyż wogóle nie odzwierciedla wykonywanej funkcji. A zatem wytłumacze pokrótce ich działanie. Na wielu profesjonalnych stronach na pewno spotkałeś się z różnego rodzaju systemami rejestracji/logowania lub licznikami odwiedzin odpornymi na przeładowania przeglądarki. To własnie w nich najcześciej wykorzystuje sie cookie lub sesje. Służą one do przechowywania danych na komputerze klienta. Dzięki ich zastosowaniu zmniejsza się ilość danych przesyłanych między stronami, a zatem jednocześnie zmniejsza się długość kodu. Technologie te są przydatne także w wielu innych przypadkach, ale nie będziemy się tu nimi zajmować. Teraz wyjaśnię różnice między sesjami a cookie. Polega ona na tym, że ciasteczka przechowują dane na komputerze klienta, a dane sesyjne przechowywane są bezpośrednio na serwerze, na którym istnieje strona. Obie można stosować zamiennie, w zależności od Twoich potrzeb.


Teraz postaram się przybliżyć Ci na przykładach konstrukcje obu tych zagadnień.

Cookies

Samo nauczenie posługiwania się ciasteczkami nie powinno sprawić Ci żadnych trudności. Musisz zapamiętać jednak jedną rzecz, która ma podobne uzasadnienie przy sesjach: aby wysłać cookie lub zainicjować sesje musisz to zrobic zanim wyślesz nagłówki do serwisu, a zatem przed znacznikiem <html> i <head> w dokumencie. Jeśli utrwalisz sobie tą zasade, to nie będziesz miał później żadnych problemów. Dla ciekawych dodam, że jest możliwość pominięcia tej zasady za pomocą funkcji ob_start() i ob_end_flush(), które służą do buforowania informacji wyjściowych, ale o tym w innym artykule. Wracając do rzeczy chciałbym zwrócić uwagę na funkcję setcookie(), z której to właśnie będziemy korzystać w celu wysyłania ciasteczek. Pełny jej opis możesz znaleźć w dokumentacji PHP, wiec postaram się tylko wyjaśnić jej działanie na przykładach. Tak więc zacznijmy od budowy funkcji:
 

setcookie('ciacho', 'wartość ciacha', time()+3600, '', http://loclhost/');



Jak zapewne zauważyłeś funkcja ta posiada aż sześć argumentów, ale nie wszystkie są obowiązkowe - są opcjonalne. Dodam jeszcze, że istnieje jeszcze jeden argument, ale nie będę go tutaj opisywał. Pierwszą wartością jaką podajemy jest nazwa ciasteczka czyli zmiennej, z której później będziemy korzystać. Następnym elementem jest wartość ciasteczka, czyli zawartość zmiennej. Trzecim argumentem jest tzw. data ważności ciasteczka. Zapewne zauważyłeś, że użyłem tu funkcji time(), która zwraca aktualny czas i do tego dodałem 3600s czyli jedną godzinę. Dzięki cookie będzie istnieć przez najbliższą godzinę. Jest to przydatne w przypadku, gdy nie chcemy, aby dana sesja nie była wykorzystywana zbyt długo, gdyż może to zaszkodzić prywatności użytkowników. Poza tym warte zwrócenia uwagi jest, że jeśli nie podamy ważności ciasteczka to będzie one aktywne aż do wyłączenia przeglądarki. Czwartym argumentem jest ścieżka, do której odwołuje się cookie. Ostatnim opisywanym przeze mnie argumentem będzie domena, czyli dla jakiej domeny będzie działało cookie. Jest to zabezpieczenie w przypadku, gdy ktoś z innej domeny chce pobrać dane z twojego serwera.
Bardzo ważne jest także to, że ciasteczko widziane jest przez serwer dopiero po przeładowaniu przeglądarki, więc w różnych sytuacjach okaże się, że wartość cookie będziesz musiał najpierw zapisać w zmiennej i wysłać ciasteczko o takiej samej nazwie, a wartość podać poprzez zmienną, np.:
 

$ciacho = 'jakas wartosc';
setcookie('ciacho', $ciacho);



Skoro już wiesz czym charakteryzują się poszczególne elementy funkcji setcookie(), to teraz opiszę jej działanie na przykładach.
Na dobry początek stworzymy prosty licznik odwiedzin, który w celu zablokowania podbijania jego wartości przez tego samego użytkownika będzie wykorzystywał właśnie cookie.
Ponieważ Nasz licznik musi jakoś przechowywać bieżącą wartość licznika należy stworzyć plik tesktowy, który będzie zastępował bazę danych. W tym celu otwórz dowolny edytor tekstowy i zapisz nowy dokument jako 'dane.txt'. Teraz przystąpimy do tworzenia samego skryptu zliczającego odwiedziny. Ponownie otwórz dowolny edytor tekstowy i zapisz nowy projekt, np. jako 'licznik.php'. Następnie postępuj zgodnie z podanymi wskazówkami.
Najpierw musimy stworzyć część skryptu, która będzie zawierała wszystkie ustawienia:
 

<?
// Dane :
$dane = 'dane.txt'; // plik z bieżacą liczbą odwiedzin
$ip = $REMOTE_ADDR; // numer IP osoby odwiedzającej
$datar = date("Ymd"); // aktualna data



Teraz stworzę prostą funkcję, która będzie odpowiadała za zapis danych do pliku:
 

function zlicznik ($plik, $licznik) {
$plik = fopen($plik, "w+");
flock($plik, 2);
fputs($plik, $licznik);
flock($plik, 3);
fclose($plik);
return 1;
}



Prawdopodobnie opanowałeś już podstawy pracy na plikach tekstowych, więc nie będę opisywał dokładnie wymienionej wyżej funkcji.
Skoro mamy już podstawowe dane możemy przystąpić do tworzenia pierwszego etapu skryptu. Do odczytu bieżącej wartości licznika posłużymy się poniższą konstrukcją:
 

if (file_exists($dane)) {
$plik = fopen($dane, 'r');
flock($plik, 1);
rewind($plik);
$licznik = trim(fgets($plik, 1024));
fclose($plik);
if ($licznik == '') {
$licznik = 0;
}
} else {
$licznik = 0;
}



Teraz zaprezentuję działanie ciasteczek. Aby ograniczyć czas wykonywania kodu proponuję stworzyć warunek, który będzie sprawdzał, czy dany użytkownik był już w bieżącym dniu na stronie. W przypadku, gdy jest to jego pierwsza wizyta, to wysyłane jest ciasteczko z datą odwiedzin.
 

if (!$odw["$ip"] || $odw["$ip"] < $datar) {
$odw["$ip"] = $datar;
setcookie("odw[$ip]", $odw["$ip"], time()+86400);



Mamy już mechanizm sprawdzający liczbę wizyt w danym dniu przez jednego użytkownika, więc teraz możemy przystąpić do zapisu wartości licznika do pliku tekstowego:
 

$licznik++;
zlicznik($dane, $licznik);



W podanym wyżej kodzie posłużyłem się skonstruowaną wcześniej funkcją, która zapisuje dane do pliku tesktowego.
Skoro zakończyliśmy już sprawdzanie i zapis danych możemy zamknąć otwartą wcześniej klamre warunku:
 

}



Na zakończenie możemy wyświelić wynik naszego licznika:
 

print "<html>\n
<head>\n
<title>Licznik odwiedzin</title>\n
</head>\n
<body>\n";
if (isset($licznik)) {
print "Wartość licznika wksazuje na: <b>$licznik</b>\n";
} else {
print "Nie można wyświetlić wartości licznika!";
}
print "</body>\n
</html>\n";
?>



Jak widać zbudowanie takiego licznika nie jest zbyt trudne, ale ta umiejętność też wymaga nie lada poświęcenia.
Przypuszczam, że zapoznałeś się już z zasadą działania cookie, a zatem przejdę do następnego etapu - opiszę sposób użytkowania z sesji.

Sesje

Zasada działania sesji jest bardzo podobna do cookie. Największa różnica polega na tym, że sesja przechowuje dane na serwerze, a cookie na komputerze klienta. Aby zarejestrować daną sesyjną będziemy się posługiwać zmienną $_SESSION, choć istnieje odpowiadająca za to funkcja. Stwierdzono jednak, że jej stosowanie może powodować luki w bezpieczenej transmisji danych.
Dodatkowo będziemy korzystać jeszcze z funkcji session_start(), session_unset(), session_destroy(), których całkowite działanie opsiano w dokumentacji PHP. Powiemiem tylko po krótce, że session_start() inicjalizuje sesję, session_unset() usuwa wszystkie zmienne sesyjne, a session_destroy() niszczy wszystkie dane sesyjne. Nową rzeczą jakiej nie było w przypadku cookie jest zmienna SID, która zawiera ID bieżącej sesji. Gdyby jej nie było, to po każdym przeładowaniu przeglądarki użytkownik otrzymywał by nową sesję i ich stosowanie okazało by się niepotrzebne. Musisz zapamiętać jednak jeszcze jedną bardzo ważną związaną z tym rzecz. A mianowicie przy inicjalizacji sesji zmienna SID jest zawsze dołączana do adresu metodą GET i automatycznie jest generowane ciasteczko z tą zmienną. Jeśli jednak użytkownik ma wyłączoną obsługę cookie to zmienna ta przepada. W celu utrzymania w dalszym ciągu takiej sesji, należałoby dołączyć do każdego hiperłącza i formularza na stronie taką właśnie zmienną:
 

<?
print "<a href=http://www.strona.pl/index.php?PHPSESSID=".SID."'>jakis_link</a>\n";
?>



lub
 

<?
print "<form>\n
<input type=hidden name=PHPSESSID value='".SID."'>\n
...
</form>\n";
?>



Warto zwrócić także uwagę na fakt, iż podobnie jak w przypadku cookie sesja jest aktywowana dopiero po przeładowaniu przeglądarki. Trzeba także pamiętać, że sesję i zmienne sesyjne trzeba inicjować przed wysłaniem nagłówków HTTP, czyli przed znacznikami <html> i <head>.
Zapoznałeś się już z uwagami dotyczącymi korzystania z sesji, a więc przejdę do konkretnego przykładu. Stworzymy prosty system logowania, który będzie się opierał właśnie na sesjach. Aby tego dokanać najpierw otwórz dowolny edytor tekstowy i zapisz nowy projekt jako 'logowanie_s.php'. Po tym fakcie przystąpimy do wprowadzenia początkowego kodu, który będzie zawierał wszystkie dane potrzebne do naszego skryptu:
 

<?
// Dane:
$strona_g = 'logowanie_s.php'; // strona główna skryptu
$plogin = 'login'; // login użytkownika
$phaslo = 'haslo'; // haslo użytkownika



Teraz możemy przejść do stworzenia głównej struktóry skryptu. Na początku sprawdzamy czy dany użytkownika chce się wylogować i jeśli nie to sprawdzany jest następny warunek:
 

if ($wyloguj) {
session_unset();
session_destroy();
header("Location: $strona_g");
} elseif (!$_SESSION["zalogowany"] || $_SESSION["zalogowany"] != 1) {



W tym momencie sprawdziliśmy czy podany użytkownik jest już zalogowany i jeśli nie to próbuje go zalogować:
 

if ($login && $haslo) {
if ($login == $plogin && $haslo == $phaslo) {
$_SESSION["login"] = $login;
$_SESSION["haslo"] = $haslo;
$_SESSION["zalogowany"] = 1;
header("Location: $strona_g");
} else {
$log = 1;
}
} else {
$log = 2;
}
}



Po sprawdzeniu czy użytkownik wprowadził dane następuje sprawdzenie poprawności danych i zapisanie ich do sesji, a następnie przeładowanie strony za pomocą funkcji header(). W przypadku, gdy odwiedzający nie podał danych, bądź były one nieprawidłowe, zmiennej '$log' nadawane są specjalne wartości, które spowodują w poźniejszej części skryptu wyświetlenie odpowiedniego komunikatu. Ponieważ nie będziemy sprawdzać już kolejnych warunków dotyczących statusu użytkownika pozwoliłem sobie zamknąć odpowiadający za nie nawias klamrowy.
Na zakończenie skryptu wygenerujemy odpowiednią stronę:
 


print "<html>\n
<head>\n
<title>Logowanie za pomocą sesji</title>\n
</head>\n
<body>\n
<center>\n";
if ($_SESSION["zalogowany"] == 1) {
print "Jesteś już zalogowany...
w celu wylogowania kliknij
<a href=$strona_g?wyloguj=1>tutaj</a>.";
} elseif ($log == 1) {
print "Podane dane są nieprawidłowe... <a href="$strona_g">Spróbuj ponownie</a>!\n";
} else {
print "<form method=post>\n
Podaj login:\n
<input type=text name=login><br>\n
Podaj haslo:\n
<input type=password name=haslo><br>\n
<input type=submit value=Zaloguj>\n
</form>\n";
}
print "</center>\n
</body>\n
</html>\n";
?>



Jak widać budowa takiego skryptu podobnie jak w poprzednim przykładzie nie jest trudna. Aby poszerzyć i utrwalić swoją wiedzę na ten temat proponuję porobić pare innych przykładów z wykorzystaniem tych technologii. Szybko zauważysz, że cookie i sesje staną się niezbędne w Twoich projektach.

Ocena 2.73/5 (54.63%) (432 głosów)

Komentarze:

  • Ja nie widać...
    Dodał: Gość data: 2012-04-24
    "Jak widać budowa takiego skryptu podobnie jak w poprzednim przykładzie nie jest "trudna"

    Nic nie widać przy tym formatowaniu kodu.
  • Karakany
    Dodał: miszcz data: 2019-06-10
    to iest tródne
  • no nie wiem
    Dodał: Kamilek Steinbach data: 2019-06-10
    Dobrze Pan Jacek w kompusroniku mi powiedział. Jednak co dwie głowy to nie jedna w apgrejdowaniu komputerkuw.
  • no nie wiem
    Dodał: Kamilek Steinbach data: 2019-06-10
    Dobrze Pan Jacek w kompusroniku mi powiedział. Jednak co dwie głowy to nie jedna w apgrejdowaniu komputerkuw.
  • JD
    Dodał: Basia+Cieślon data: 2019-12-16
    Essa byki jak tam u was jak wam dzien mija
  • UWAGA
    Dodał: Bogdan duda data: 2019-12-16
    Witam jestem synem znanego prezydenta polski Andrzeja Dudy może znacie może nie w dupie to mam essa


Dodaj komentarz:


Temat:
Twój nick:
Komentarz:
 

Prosimy o kulturę wypowiedzi. Komentarze zawierające niecenzuralne zwroty, bądź obrażające inne osoby będą usuwane. Kod HTML w wypowiedziach jest niedozwolony. Wydawca nie odpowiada za treść komentarzy.