r06_t.pdf

(271 KB) Pobierz
Oto przyk³ady stylów nag³ówków:
Rozdział 6
Zapamiętywanie informacji o odwiedzających
W niniejszym rozdziale omówimy następujące tematy:
Wprowadzenie do zagadnienia cookies.
Tworzenie i manipulowanie cookies za pomocą funkcji PHP setcookie.
Określanie restrykcji, takich jak czas obowiązywania cookies.
Połączenie powyższych elementów w aplikacji Flasha Cookie Cutter.
Jedna z najbardziej użytecznych funkcji każdej witryny sieci Web jest możliwość zapamiętywania informacji o
odwiedzających. Do najczęściej rejestrowanych danych należą:
Nazwisko odwiedzającego oraz inne dane osobowe.
Nazwa użytkownika lub hasło.
Preferencje dotyczące witryny.
Nabywane dobra.
Zapamiętanie tych informacji może przyczynić się do ułatwienia odwiedzającym korzystania z naszej witryny i
zwiększenia produktywności. Z pewnością każdy z nas widział już witryny wyposażone w pole wyboru opcji
zapamiętania nazwy użytkownika i hasła do następnego logowania z tego samego komputera.
RYS. str. 178
Zrzut pobrany z witryny www.amazon.co.uk
Jedną z najłatwiejszych metod stosowanych przez PHP, umożliwiających zapamiętywanie danych różnego
rodzaju, od nazwy użytkownika, po jego adres, są...
Cookies
Cookies (ciasteczka),określane pierwotnie jako "magic cookies", zostały zastosowane po raz pierwszy przez
Netscape i zintegrowane z przeglądarką sieciową. Mogą one być użyte do zapamiętywania informacji o
określonym użytkowniku.
Wspaniałą cechą cookies jest to, że są one przechowywane w komputerze użytkownika, co oznacza, że nie
dotyczy nas problem jak i gdzie je zapisywać. Choć w niektórych przypadkach sytuacja ta bywa nieco inna, to
jednak większość przeglądarek przechowuje cookies w postaci niewielkich plików tekstowych, zapisywanych
na twardym dysku użytkownika.
W najprostszej formie, cookies mogą być użyte do zapamiętania imienia czy nazwiska odwiedzającego, co
pozwala na spersonalizowanie powitania podczas kolejnej wizyty na witrynie. W najbardziej złożonej postaci,
cookies można wykorzystać podczas tworzenia aplikacji typu "koszyk na zakupy", zapamiętując w nich dane
dotyczące zakupionych dóbr i ich ilości. Fakt, że dane te są przechowywane po opuszczeniu witryny przez
odwiedzającego i udostępniane podczas kolejnej jego wizyty, stanowi o możliwości wykorzystania cookies
przez zmienne globalne definiowane na witrynie Flasha.
Każdy z nas widział witryny Flasha z przyciskiem Skip Intro (Pomiń intro), ale cóż możemy powiedzieć na
temat cookies, które zapamiętują czy odwiedzający owo intro obejrzał czy nie, powodując jego pominięcie przy
kolejnych wizytach — dzięki PHP jest to bardzo łatwe do osiągnięcia, a wkrótce przekonamy się jak łatwe!
Zgodnie ze specyfikacją cookies opracowaną przez Netscape, na cookies zostały nałożone pewne restrykcje,
zapobiegające nadużyciom. Po pierwsze, przeglądarka sieci Web nie powinna przechowywać więcej iż 300
1
cookies. przy czym pojedynczy serwer powinien mieć możliwość ustawienia nie więcej niż 20 cookies. Ponadto,
objętość pojedynczego cookie musi wynosić najwyżej 4 kilobajty. Chcąc przechować więcej informacji, należy
je zachować po stronie serwera (na przykład, w bazie danych), zaś zamiast cookie przekazać pewnego rodzaju
identyfikator.
Inną zasadą bezpieczeństwa, dotyczącą jednak zachowania prywatności danych, a nie ich integralności, jest to,
że cookies mogą być przesyłane jedynie do serwerów mających upoważnienie do ich odbierania i zazwyczaj
witryny generujące cookies mają możliwość ich odczytywania. Gdy zaczniemy zgłębiać zagadnienia związane z
cookies, dowiemy się, ze możliwe jest ustanawianie ograniczeń oraz warunków, jakie muszą spełniać serwery
upoważnione do odbioru ciasteczek.
Cookies są wykorzystywane przez ogromną liczbę witryn. Jeśli przeglądarka je obsługuje, warto włączyć
funkcję zatwierdzania przyjmowania cookies i zajrzeć na ulubione witryny — można się zdumieć widząc ile z
nich zbiera informacje na temat naszych wizyt.
Aby przeprowadzić taki eksperyment, posłużmy się poniższym rysunkiem, wybierając opcję Poziom
niestandardowy, na karcie Zabezpieczenia, wywołując ją za pomocą polecenia Opcje internetowe z menu
Narzędzia. Możemy tu wybrać opcję zatwierdzania przyjmowania cookies, a następnie przystąpić do
obserwacji!
Wykonując opisane tu zabiegi, powinniśmy jednak pamiętać, że ciasteczka nie są podstępnymi z natury
urządzeniami inwigilacyjnymi — przechowują one tylko te informacje, jakie sami podamy, odwiedzając
witrynę.
Restrykcje dotyczące cookies
Wewnątrz cookies możemy zawrzeć cztery rodzaje informacji, które powinniśmy tu omówić.
Data upływu ważności
Każde ciasteczko ma wyznaczoną datę upływu ważności — datę przydatności do spożycia, jak kto woli! Po
upływie tego terminu, ciasteczko nie jest już przesyłane do serwera i w większości przypadków ulega usunięciu
z systemu. Jeśli termin ten nie zostanie określony podczas tworzenia ciasteczka, wówczas jest ono usuwane
wraz z zamknięciem bieżącej sesji przeglądarki (gdy użytkownik zamyka przeglądarkę). Jest to wygodna
metoda tworzenia cookies tymczasowych, zapamiętujących czy użytkownik dokonał logowania, czy też nie.
Domena
Kiedy przeglądarka wyszukuje aktualnych cookies do wysłania pod adres serwera, atrybut domeny
porównywany jest z nazwą domeny serwera, do którego ciasteczko ma powędrować. Porównanie to polega na
sprawdzeniu końcówki cookie, i dopasowaniu jego atrybutu domeny do końcówki nazwy domeny serwera.
Na przykład, atrybut domeny .codejunkie.co.uk pasuje do adresu www.codejunkie.co.uk , jak również
another.partof.codejunkie.co.uk . Jeśli te domeny zostaną dopasowane, wówczas przychodzi moment analizy
atrybutu ścieżki.
Cookie może być zdefiniowane tylko dla danej domeny, jeśli żądanie pochodzi z hosta w tej właśnie domenie.
Domyślną wartością atrybutu domeny jest nazwa hosta obsługującego serwer generujący żądanie.
Ścieżka
Atrybut ścieżki zapisany w ciasteczku służy do określania podzestawu adresów URL w domenie, dla której
cookie zostało zdefiniowane. Jeśli dopasowanie zostanie zakończone powodzeniem, cookie jest uznawane za
poprawne dla bieżącej witryny i przesyłane dalej wraz ze standardowym nagłówkiem HTTP.
Przykładowo, jeśli cookie ma zdefiniowaną ścieżkę /news, wówczas staje się dostępne dla /newsletter.php, a
także wszystkich plików w ścieżkach /newsamples i /news. Praktycznie rzecz biorąc, cookie będzie dostępne dla
każdego elementu, którego nazwa rozpoczyna się od /news, czy to katalogu, czy pliku. Aby udostępnić
ciasteczko całej domenie, należy ustawić ścieżkę na "/".
Jeśli cookie nie ma zdefiniowanego atrybutu ścieżki, wówczas przyjmuje ono ścieżkę pliku żądającego jego
ustawienia.
Bezpieczeństwo
2
Ostatnim obostrzeniem jest atrybut bezpieczeństwa ciasteczka. Jeśli cookie zostanie oznaczone jako
zabezpieczone, wówczas jest ono przesyłane do serwera jedynie wtedy, gdy kanał komunikacyjny z hostem jest
również zabezpieczony. To z kolei oznacza, że ciasteczka zabezpieczone są wysyłane do serwera jeśli
połączenie korzysta z protokołu Secure Socket Layer (SSL) — innymi słowy, jeśli jego adres URL rozpoczyna
się od https:// zamiast http://.
PHP lubi ciasteczka...
Jak można się domyślić, na podstawie obszernego omówienia tematu cookies w niniejszej książce, ich obsługa
jest integralną częścią PHP, co pozwala nam na wykorzystanie ciasteczek w skryptach i to niedużym nakładem
pracy. Na przykład, odczytywanie cookies wewnątrz PHP jest równie proste jak uzyskiwanie dostępu do
zmiennych. Dzieje się tak dlatego, ponieważ każde ciasteczko zatwierdzone dla bieżącego dokumentu jest
automatycznie udostępniane jako zmienna globalna, dokładnie w taki sam sposób, jak dane POST i GET .
Następuje to zanim jakikolwiek kod zawarty w skrypcie PHP zostanie wykonany.
Ta łatwość poszerza również możliwości ustawiania cookies za pomocą PHP. Można tego dokonywać poprzez
pojedyncze wywołania funkcji, która w najprostszej postaci akceptuje dwa argumenty: nazwę i wartość
ciasteczka. Nic dziwnego, że funkcji tej nadano nazwę setcookie — wystarczająco prostą, aby każdy ją
zapamiętał!
Ustawianie ciasteczek
Przyjrzyjmy się działaniu setcookie...
<?
// Increment number of visits count
// If count isn't set then it will be set to 1
$count++;
// Store the cookie on the user's system
setcookie('count', $count);
// Output message
print "You have visited this site $count time(s).\n";
?>
Gdy uruchomimy powyższy skrypt, inicjalizowana jest zmienna $count z przypisaną wartością '1' — dzieje się
tak w przypadku każdej nieistniejącej zmiennej, inkrementowanej w sposób podobny do zastosowanego tutaj.
Następnie, cookie jest wysyłane do klienta pod nazwą count . Na koniec, za pomocą prostej instrukcji print ,
wyświetlana jest bieżąca wartość $count .
Wszystko staje się interesujące, gdy skrypt zostanie załadowany po raz drugi. Ponieważ cookie egzystuje pod
nazwą count , automatycznie wygenerowana zostaje zmienna globalna o tej samej nazwie, a przypisywana jej
wartość jest wartością ciasteczka. Procesy te zachodzą przed wykonaniem skryptu, a więc jeśli zwiększymy
wartość zmiennej $count , będzie ona przechowywała wartość większą o jeden od wartości zapisanej w
ciasteczku. Na koniec zaś, za pomocą wywołania setcookie uaktualniamy wartość ciasteczka zgodnie z
nową wartością $count , po czym odwiedzający ponownie otrzymuje komunikat.
Jeśli przyjrzymy się temu mechanizmowi, zauważymy, że za każdym odświeżeniem przeglądarki, liczba wizyt
na witrynie lub przynajmniej na danej stronie, ulega uaktualnieniu, czemu towarzyszy stosowny komunikat.
Jeśli powyższy przykład nie działa, wówczas należy sprawdzić, czy przeglądarka przyjmuje cookies.
Najczęstsze pułapki
Istnieje kilka pułapek, w które wpadają projektanci wykorzystujący cookies, a które uniemożliwiają ciasteczkom
działanie lub powodują pojawianie się komunikatów o błędach (a czasem jedno i drugie!).
Spośród wszystkich, najczęściej popełnianym błędem jest wysyłanie informacji przed wywołaniem
setcookie . Powinniśmy pamiętać bowiem o tym, że ciasteczka stanowią część nagłówków HTTP, a w
3
związku z tym wywołanie setcookie musi następować przed instrukcjami wyświetlania informacji, takimi
jak print czy echo. Dotyczy to także wszelkich pustych znaków przed otwierającym znacznikiem PHP.
Jeśli zdarzy nam się ujrzeć komunikat o błędzie, jak na poniższym rysunku, wówczas należy cofnąć się i
skontrolować skrypty pod kątem generowania wyników przed wywołaniem setcookie .
Kolejna, częsta pomyłka polega na założeniu, że cookie staje się dostępne dla skryptu natychmiast po
wywołaniu funkcji setcookie .
<?
setcookie('username', 'steve');
print "Username: $username";
?>
Słuszne może wydawać się założenie, że powyższy skrypt powinien dawać wynik taki jak na rysunku po prawej
stronie.
Jednakże, podczas pierwszego uruchomienia skryptu wynik będzie inny, co wynika ze sposobu działania
cookies w skryptach po stronie serwera. Po wywołaniu tego skryptu, wszystkie poprawne ciasteczka są
wysyłane do serwera. Choć wywołując setcookie nakazujemy przeglądarce utworzenie i zachowanie
ciasteczka o nazwie username , nie zostanie ono odesłane do serwera aż do kolejnego uruchomienia skryptu.
Dlatego też, poprawne wyniki otrzymamy dopiero podczas jego następnych uruchomień.
RYS. str. 185
Pierwsze uruchomienie
Kolejne uruchomienia
Kto zjadł wszystkie ciasteczka?
Dostępność cookies jako zmiennych globalnych jest ich dużą zaletą, ale co począć, jeśli zechcemy przetworzyć
wszystkie dostępne ciasteczka? W jaki sposób mamy odróżnić, które zmienne globalne powstały w wyniku
przetworzenia ciasteczek, a które pochodzą z innych źródeł, jakimi mogą być, na przykład, dane POST i GET ?
Ponadto, mechanizm automatycznego tworzenie zmiennych globalnych w PHP powinien unikać, na tyle na ile
się da, ryzyka związanego z bezpieczeństwem. Niestety, opisywana tu metoda ustawiania cookies ma charakter
jedynie ćwiczenia, a w dalszych, bardziej zaawansowanych skryptach, zostanie zastąpiona. Czym jednak można
ją zastąpić?
Odpowiedź brzmi: tablicą $HTTP_COOKIE_VARS . Każde ciasteczko przesłane do serwera, poza pełnieniem
roli budulca dla zmiennej globalnej, zapisywane jest w tej tablicy. Pozwala to przetwarzać wszystkie lub tylko
wybrane spośród dostępnych ciasteczek za pomocą procedur zapętlania tablicy, o których mówiliśmy w
Rozdziale 2.
Użyjmy teraz klawiatury i wpiszmy poniższy kod lub, jeśli zabraknie nam ochoty na pisanie, po prostu
otwórzmy plik źródłowy.
<?
// httpcookievars.php
// Chapter 6 - Foundation PHP for Flash
// Set up some cookies...
setcookie('username', 'steve');
setcookie('password', 'nottelling');
setcookie('skipintro', 'true');
// Determine the number of cookies currently set
$cookieCount = count($HTTP_COOKIE_VARS);
// If we've got more than one cookie...
if ($cookieCount > 0) {
// Output header
print "Cookies found: $cookieCount <BR><BR>\n\n";
// Loop through all cookies...
4
foreach($HTTP_COOKIE_VARS as $cookieName => $cookieValue) {
// Output name/value
print "$cookieName=$cookieValue <br>\n";
}
} else {
// Otherwise output "no cookies" msg
print 'No cookies available, hit refresh';
}
?>
Korzystamy tu z pętli foreach (zaimplementowanej w 4 wersji PHP), która przebiega przez tablicę, w której
zawarte są cookies, zwracając je pojedynczo w kolejnych przebiegach. Skrypt powyższy, po uruchomieniu,
powinien dać wynik podobny do widocznego na rysunku.
RYS> str. 186.
Odświeżanie
Jak widać, po pierwszym uruchomieniu skryptu żadne ciasteczko nie jest wyświetlane, w związku z czym
należy odświeżyć dokument prezentowany przez przeglądarkę. Skrypt ten demonstruje potęgę, jaką daje
możliwość tworzenia i wywoływania cookies z PHP!
Czas życia ciasteczka
Zaprezentowany powyżej przykład jest całkowicie poprawny, ale jeżeli zamkniemy okno przeglądarki, po czym
otworzymy ją, ponownie wczytując odwiedzoną stronę, licznik odwiedzin ulegnie zresetowaniu do wartości 1.
Ponieważ nie wyznaczyliśmy daty ważności ciasteczka, przeglądarka usunie je wraz z zakończeniem sesji lub
zamknięciem okna. Choć rozwiązanie to jest wystarczające do przechowywania takich informacji jak status
zalogowanego użytkownika, to jednak naszym celem jest przechowywanie danych w ciasteczkach w bardziej
trwały sposób.
Aby wydłużyć czas życia ciasteczka, poza sesję bieżącą, należy wyznaczyć datę, do której ciasteczko będzie
obowiązywało. Możemy to zrobić bez trudu, uzupełniając listę parametrów funkcji setcookie o jeden
dodatkowy, ale niestety nie możemy określić daty za pomocą łańcucha.
Krótka historia time()
Zamiast formatu daty czytelnego dla człowieka, na przykład 27/02/2002 21:15:00, określając datę ważności
ciasteczka musimy posłużyć się unixowym znacznikiem czasu (Unix Timestamp). Może to z początku brzmieć
groźnie, ale tylko do czasu, gdy przekonamy się, że znacznik ten jest po prostu liczbą sekund, które upłynęły od
1 stycznia 1970 — od daty określaną często jako data początku epoki.
Niektórzy mogą się w tym momencie przestraszyć mozolnych obliczeń, ale nie ma powodu do takich obaw! Nie
musimy przeistaczać się w biednego użytkownika Unixa, który liczy sekundy, jakie upłynęły od 1970 roku, nie
mogąc nawet skorzystać z toalety. PHP wspiera nas bardzo przydatną, niepozorną funkcją, przeliczającą czas
bieżący na wartość unixowego wskaźnika czasu. Jak większość funkcji PHP, tak i ta otrzymała bardzo
intuicyjną nazwę time() .
Składnia funkcji time jest najprostsza, z jaką przyszło nam się dotychczas spotkać:
time();
Nie podając żadnych argumentów, wystarczy zwyczajnie wywołać time , a zwróconą wartość integer
przechować w zmiennej i wykorzystać ją w odpowiednim momencie.
Na przykład, wpisując poniższy kod możemy zbadać bieżący czas jako liczbę sekund, które upłynęły od
początku epoki i zapisać go w zmiennej $now :
<?
// Fetch current time as no. of seconds since epoch
$now = time();
print $now
?>
5
Zgłoś jeśli naruszono regulamin