You are on page 1of 49

IDZ DO

PRZYKADOWY ROZDZIA
SPIS TRECI

KATALOG KSIEK
KATALOG ONLINE

PHP. Rozmwki
Autor: Christian Wenz
Tumaczenie: Radosaw Meryk
ISBN: 83-246-0324-7
Tytu oryginau: PHP Phrasebook
Format: B5, stron: 360

ZAMW DRUKOWANY KATALOG

TWJ KOSZYK
DODAJ DO KOSZYKA

CENNIK I INFORMACJE
ZAMW INFORMACJE
O NOWOCIACH
ZAMW CENNIK

CZYTELNIA
FRAGMENTY KSIEK ONLINE

Wydawnictwo Helion
ul. Chopina 6
44-100 Gliwice
tel. (32)230-98-63
e-mail: helion@helion.pl

Jzyk PHP to jedna z najpopularniejszych platform programistycznych sucych do


tworzenia aplikacji internetowych. Wszdzie tam, gdzie zamierzamy dynamicznie
generowa tre witryny, gromadzi i przetwarza dane, identyfikowa uytkownikw
strony lub wysya pliki do witryny WWW, wykorzystujemy PHP. Gdy pojawiaj si
problemy, wertujemy ksiki, szukajc porad i przykadw. Jeli przydatne wskazwki
znajduj si w jednym miejscu, praca szybko posuwa si do przodu.
Ksika PHP. Rozmwki to zbir ponad 100 przykadw kodu opatrzonych
komentarzami i dokadnie przetestowanych w rnych systemach operacyjnych
i przegldarkach. Autor podpowiada gotowe rozwizania problemw, z ktrymi borykaj
si na co dzie programici PHP. Przykadowy kod z atwoci mona dostosowa
do wasnych potrzeb, przyspieszajc w ten sposb prac nad aplikacj i zwikszajc
produktywno.
Operacje na acuchach tekstowych
Stosowanie wyrae regularnych
Przetwarzanie tablic
Operacje na datach
Obsuga formularzy WWW
Uwierzytelnianie uytkownikw
Stosowanie plikw cookie i mechanizmw sesji
Praca z systemem plikw na serwerze
Poczenia z bazami danych
Przetwarzanie dokumentw XML
Komunikacja z usugami sieciowymi
Do efektywnej pracy z PHP wystarczy ta ksika
zatem po co korzysta z opasych tomw?

Spis treci
O autorze ............................................................................11
Wprowadzenie ...................................................................13
1 Operacje na cigach znakw ..............................................17
Porwnywanie cigw znakw ...............................................18
Sprawdzanie poprawnoci nazw uytkownikw i hase ...........19
Przeksztacanie cigw znakw na jzyk HTML .......................21
Zastosowanie znakw podziau wiersza ..................................24
Szyfrowanie cigw znakw ...................................................25
Sprawdzanie sum kontrolnych cigw znakw .......................27
Wydzielanie podcigw znakw ...............................................29
Zabezpieczanie adresw e-mail za pomoc kodw ASCII ........30
Skanowanie sformatowanych cigw znakw ........................35
Pobieranie szczegowych informacji o zmiennych ..................36
Wyszukiwanie w cigach znakw ...........................................37
Wykorzystanie wyrae regularnych POSIX .............................41
Wykorzystanie wyrae regularnych zgodnych z Perlem ..........43
Wyszukiwanie znacznikw za pomoc wyrae regularnych ......44
Sprawdzanie poprawnoci pl obowizkowych ......................45

Spis treci

Sprawdzanie poprawnoci liczb i danych innych typw .......... 47


Sprawdzanie poprawnoci adresw e-mail ............................. 49
Wyszukiwanie z zastpowaniem ................................................ 51
2 Tablice ................................................................................55
Dostp do wszystkich elementw tablicy numerycznej .............. 57
Dostp do wszystkich elementw tablicy asocjacyjnej ............ 59
Dostp do wszystkich elementw tablicy zagniedonej ......... 60
Przeksztacanie elementw tablic na zmienne ........................ 63
Konwersja cigw znakw na tablice ..................................... 64
Konwersja tablic na cigi znakw ........................................... 65
Alfabetyczne sortowanie tablic ............................................... 66
Alfabetyczne sortowanie tablic asocjacyjnych ......................... 68
Sortowanie tablic zagniedonych .......................................... 70
Sortowanie zagniedonych tablic asocjacyjnych .................... 72
Sortowanie adresw IP (tak jak robiliby to ludzie) .................. 74
Sortowanie niestandardowe ................................................... 76
Sortowanie z wykorzystaniem znakw narodowych ............... 77
Wykonywanie operacji dla wszystkich elementw tablicy ....... 80
Filtrowanie tablic ................................................................... 83
Losowe pobieranie elementw z tablicy ................................. 84
3 Daty i godziny .....................................................................87
Wykorzystanie tekstu wewntrz funkcji date() ........................ 90
Automatyczna lokalizacja dat ................................................. 92
Rczna lokalizacja dat ............................................................ 96
Wykorzystanie daty biecej w formacie US, UK i europejskim .... 97
Formatowanie dowolnych dat ................................................ 98
Sprawdzanie poprawnoci dat ............................................... 99
Wykonywanie oblicze z datami ............................................. 100
Tworzenie znacznikw czasu, ktre mona sortowa ............ 101
4

Spis treci

Konwersja cigw znakw na daty .......................................103


Okrelanie czasu wschodu i zachodu soca ..........................104
Wykorzystanie dat i godzin do testw
szybkoci dziaania sprztu lub programw .......................106
Zastosowanie pl formularzy do wyboru dat .........................108
Tworzenie samouaktualniajcych
si pl formularzy do wyboru dat ......................................110
Obliczanie rnicy pomidzy dwiema datami ........................112
Wykorzystanie informacji o dacie i godzinie wedug GMT .....115
4 Interakcje z formularzami WWW ......................................117
Przesyanie danych formularza do biecego skryptu ............119
Odczyt danych formularzy .....................................................119
Magiczne cudzysowy (apostrofy) ..........................................123
Sprawdzenie, czy przesano formularz ...................................124
Zapisywanie danych formularzy w plikach cookie ..................126
Wypenianie pl tekstowych
i pl hase danymi pocztkowymi ......................................129
Wypenianie wielowierszowych
pl tekstowych danymi pocztkowymi ...............................132
Domylne wartoci przecznikw .........................................134
Wypenianie pl wyboru danymi pocztkowymi ...................136
Wypenianie list wyboru danymi pocztkowymi ....................137
Wypenianie list wielokrotnego
wyboru danymi pocztkowymi ..........................................139
Przetwarzanie graficznych przyciskw Submit .......................142
Sprawdzanie pl obowizkowych .........................................144
Sprawdzanie poprawnoci list wyboru ..................................146
Zapisywanie wszystkich danych formularza w pliku ..............149
Wysyanie wszystkich danych formularza poczt elektroniczn ..151
5

Spis treci

Pobieranie informacji na temat plikw


wgrywanych na serwer ..................................................... 153
Przenoszenie plikw wgranych
na serwer do bezpiecznej lokalizacji .................................. 156
5 Zapamitywanie ustawie uytkownikw
pliki cookie i sesje .....................................................159
Istota plikw cookie ............................................................. 160
Tworzenie plikw cookie ...................................................... 163
Odczytywanie plikw cookie ................................................ 164
Pozbywanie si magicznych cudzysoww (apostrofw)
z plikw cookie ................................................................. 166
Ustawianie daty wanoci wzgldem innej daty ................... 167
Ustawianie daty wanoci specyficznej dla klienta ................ 169
Usuwanie plikw cookie ...................................................... 170
Udostpnianie plikw cookie dla wielu domen ..................... 172
Sprawdzanie, czy klient obsuguje pliki cookie ...................... 174
Zapisywanie wielu danych w jednym pliku cookie ................ 176
Zapisywanie ustawie jzykowych uytkownika ................... 178
Sesje .................................................................................... 181
Gdzie naley zapisywa sesje? .............................................. 182
W jaki sposb zachowa stan sesji? ..................................... 183
Aktywacja sesji .................................................................... 184
Czytanie i zapisywanie sesji ................................................. 185
Zamykanie sesji .................................................................... 186
Modyfikacje identyfikatora sesji ............................................ 187
Tworzenie dynamicznych czy z obsug sesji ...................... 188
Implementacja wasnego mechanizmu zarzdzania sesjami .. 190
Tworzenie zabezpieczonego obszaru z wykorzystaniem sesji 194
Tworzenie zabezpieczonego obszaru bez korzystania z sesji . 197

Spis treci

6 Wykorzystanie plikw zapisanych


w systemie plikw serwera ...........................................201
Otwieranie i zamykanie plikw .............................................202
Odczytywanie danych z plikw .............................................206
Zapisywanie danych do pliku ................................................208
Blokowanie plikw ...............................................................210
Wykorzystanie cieek wzgldnych
w celu uzyskania dostpu do pliku ....................................212
Unikanie niebezpiecznych puapek zwizanych
z dostpem do plikw .......................................................213
Wykorzystanie danych w formacie CSV .................................215
Przetwarzanie plikw INI ......................................................220
Odczytywanie informacji o plikach ........................................222
Kopiowanie, przenoszenie i usuwanie plikw .......................225
Przegldanie systemu plikw ................................................226
Wykorzystanie strumieni w PHP ...............................................227
Wykorzystanie archiww Bzip2 .............................................229
Zwracanie plikw za pomoc dania HTTP ..........................232
7 Tworzenie danych dynamicznych .....................................235
Nawizywanie poczenia z baz danych ..............................237
Nawizywanie poczenia z baz danych
z wykorzystaniem rozszerzenia MySQLi ................................238
Wysyanie instrukcji SQL do bazy danych MySQL ...................240
Instrukcje preparowane w MySQL-u ......................................242
Odczytywanie wynikw zapytania do bazy danych MySQL ....245
Nawizywanie poczenia z baz danych SQLite ...................248
Wysyanie instrukcji SQL do bazy danych SQLite ....................250
Odczytywanie wynikw zapytania do bazy danych SQLite .....251
Nawizywanie poczenia z baz danych PostgreSQL ............253
Wysyanie zapyta SQL do bazy danych PosgreSQL ...............255
7

Spis treci

Aktualizacja danych w PostgreSQL ....................................... 256


Odczytywanie wynikw zapytania
do bazy danych PostgreSQL .............................................. 257
Nawizywanie poczenia z baz danych Oracle .................. 259
Wysyanie instrukcji SQL do bazy danych Oracle ................... 260
Odczytywanie wynikw zapytania do bazy danych Oracle .... 263
Nawizywanie poczenia z baz danych MSSQL ................. 265
Przesyanie instrukcji SQL do bazy danych MSSQL ................. 267
Odczytywanie wynikw zapytania do bazy danych MSSQL ... 269
Nawizywanie poczenia z baz danych Firebird ................. 270
Przesyanie instrukcji SQL do bazy danych Firebird ................ 272
Odczytywanie wynikw zapytania do bazy danych Firebird .. 273
Nawizywanie poczenia z bazami danych za pomoc PDO ....... 274
Przesyanie instrukcji SQL za pomoc PDO ............................ 277
Odczytywanie wynikw zapyta przesyanych za pomoc PDO ..278
8 Wykorzystanie XML-a .......................................................281
Przetwarzanie XML za pomoc interfejsu SAX ...................... 282
Odczyt dokumentw XML
z wykorzystaniem modelu DOM w PHP 4 .......................... 285
Odczyt dokumentw XML
z wykorzystaniem modelu DOM w PHP 5 .......................... 287
Wykorzystanie modelu DOM
do zapisywania dokumentw XML w PHP 4 ...................... 289
Wykorzystanie modelu DOM
do zapisywania dokumentw XML w PHP 5 ...................... 291
Wykorzystanie rozszerzenia SimpleXML ................................ 292
Transformacje dokumentw XML
z wykorzystaniem XSL w PHP 4 ......................................... 294
Transformacje dokumentw XML
z wykorzystaniem XSL w PHP 5 ............................................. 295
Sprawdzanie poprawnoci dokumentw XML ...................... 296
8

Spis treci

9 Komunikacja ze wiatem zewntrznym ...........................299


Nawizywanie poczenia z serwerami HTTP ........................299
czenie si z serwerami FTP ................................................303
Sprawdzanie, czy serwer odpowiada ....................................305
Tworzenie usug sieciowych
z wykorzystaniem pakietu PEAR::XML-RPC ........................310
Korzystanie z usugi sieciowej
za pomoc pakietu PEAR::XML-RPC ................................312
Tworzenie usugi sieciowej za pomoc klasy NuSOAP ...........314
Automatyczne generowanie kodu WSDL
z wykorzystaniem klasy NuSOAP ........................................315
Wykorzystanie usugi sieciowej zaimplementowanej
za pomoc klasy NuSOAP ..................................................319
Tworzenie usug sieciowych
za pomoc pakietu PEAR::SOAP .........................................320
Automatyczne generowanie kodu WSDL dla usug sieciowych
zaimplementowanych za pomoc pakietu PEAR::SOAP .........322
Wykorzystanie usugi sieciowej zaimplementowanej
za pomoc pakietu PEAR::SOAP .........................................324
Tworzenie usug sieciowych
z wykorzystaniem rozszerzenia SOAP w PHP 5 ...................325
Wykorzystanie usug sieciowych tworzonych
za pomoc rozszerzenia SOAP w PHP 5 ..............................328
Skorowidz .........................................................................335

5
Zapamitywanie
ustawie uytkownikw
pliki cookie i sesje
Zapamitywanieustawieuytkownikw

HTTP (Hypertext Transfer Protocol) jest protokoem bez-

stanowym. Mwic prosto, klient (przegldarka WWW)


czy si z serwerem WWW, przesya danie i uzyskuje
odpowied. Nastpnie poczenie jest zamykane. W konsekwencji, jeli nastpnym razem ten sam klient przele danie
do tego samego serwera WWW, bdzie to nowe danie,
a zatem serwer WWW nie bdzie mg zidentyfikowa
uytkownika. Takie dziaanie stanowi oczywisty problem
dla aplikacji, ktre musz utrzymywa stany (na przykad
aplikacji e-commerce z implementacj koszyka na zakupy).
Z ograniczeniem tym mona jednak sobie poradzi na kilka
sposobw. Podstawowa idea polega na przesaniu pewnych informacji wraz z odpowiedzi HTTP. Informacje
te s przesyane do serwera we wszystkich kolejnych daniach. Istniej nastpujce moliwoci:

ROZDZIA 5

ZAPAMITYWANIE USTAWIE UYTKOWNIKW

Istota plikw cookie

wysanie danych za pomoc metody POST (tzn. za


kadym razem wymagany jest formularz),

wysanie danych za pomoc metody GET (tzn. poprzez doczenie informacji do adresu URI dania),

wysanie danych jako czci nagwka HTTP (w postaci pliku cookie).

W praktyce uywa si jednej z dwch metod: sesji (z wykorzystaniem metody GET lub plikw cookie) oraz plikw cookie.

Istota plikw cookie


Pliki cookie s przesyane w nagwkach HTTP. W uproszczeniu, plik cookie skada si z pary nazwa-warto. Najwaniejsz wad plikw cookie jest moliwo ich blokowania
w przegldarkach WWW (a take filtrowania na serwerach proxy). Niektrzy uwaaj, e pliki cookie stanowi
zagroenie dla prywatnoci uytkownikw. Po czci przyczyn tego pogldu by artyku Johna Udella z marca 1997
roku, w ktrym autor stwierdzi, e kady plik cookie
mona odczyta z kadego serwera WWW, a zatem wczenie obsugi plikw cookie oznacza utrat prywatnoci.
Artyku spowodowa zamieszanie. Niestety, sprostowanie opublikowane dwa miesice pniej nie wzbudzio
ju takiego zainteresowania.
Prawd jest, e pliki cookie maj pewne ograniczenia:

160

s powizane z domenami zazwyczaj z domen,


z ktrej wysano plik cookie,

mog by powizane z katalogami na serwerze WWW,

zawieraj wycznie informacje tekstowe; maksymalnie


4096 bajtw (wcznie z nazw pliku cookie i znakami = pomidzy nazwami a wartociami),

przegldarki mog zaakceptowa tylko do 20 plikw


cookie na domen i 300 plikw cookie w ogle (cho
niektre przegldarki akceptuj wicej).

UWAGA
Nieoficjalna specyfikacja plikw cookie jest zwizana z przegldark Netscape i cigle jest dostpna pod adresem http://
wp.netscape.com/newsref/std/cookie_spec.html. Byy prby
stworzenia specjalnego dokumentu RFC dotyczcego plikw
cookie nowej generacji, ale inicjatywy te nie doczekay si
jeszcze obsugi w adnej z popularnych przegldarek.
Pliki cookie s przesyane w nagwkach HTTP. W przypadku ustawienia pliku cookie w nagwku HTTP tworzy
si zapis Set-Cookie. Dalej wystpuje nazwa i warto
pliku cookie (obie w postaci cigu znakw) oraz opcjonalnie inne informacje, takie jak data wanoci, domena
i cieka dostpu do pliku cookie. Na przykad, jeli odwiedzimy witryn http://www.php.net, witryna PHP przele
nagwek w nastpujcej postaci (oczywicie ustawienia
jzyka i adres IP mog by inne):

ZAPAMITYWANIE USTAWIE UYTKOWNIKW

ROZDZIA 5

Istota plikw cookie

Set-Cookie:COUNTRY=DEU%2C84.154.17.84; expires=Thu
19-May-05 15:23:29 GMT; path=/; domain=.php.net

161

ROZDZIA 5

ZAPAMITYWANIE USTAWIE UYTKOWNIKW


162

Istota plikw cookie

Kiedy przegldarka (lub uytkownik) zaakceptuje plik cookie, zostanie on przesany na serwer podany w nagwku
HTTP Cookie:
Cookie:COUNTRY=DEU%2C84.154.17.84

Dla pliku cookie mona ustawi dat wanoci. Jeli zostanie ustawiona, plik bdzie przechowywany co najwyej
do tej daty. Jest to tzw. trway plik cookie (ang. persistent
cookie). Po upywie tego okresu przegldarka automatycznie go usunie cho moe to rwnie zdarzy si
wczeniej; na przykad w przypadku zapisania maksymalnej liczby plikw cookie w przegldarce najstarsze pliki
cookie zostan usunite. Jeli data wanoci pliku cookie
nie zostanie ustawiona, taki plik okrela si jako tzw.
plik sesji lub plik tymczasowy. Pliki cookie tego typu s
przechowywane tak dugo, jak dugo dziaa przegldarka
WWW. Podczas zamykania przegldarki tymczasowe pliki
cookie s usuwane.
WSKAZWKA
Aby oglda nagwki HTTP, mona skorzysta ze specjalnych
rozszerze standardowych przegldarek WWW. W przypadku
przegldarek Mozilla (wcznie z przegldark Firefox) wielkie
moliwoci oferuje rozszerzenie LiveHTTPHeaders dostpne
pod adresem http://livehttpheaders.mozdev.org/. Uytkownicy
przegldarki Microsoft Internet Explorer mog zainstalowa
pasek narzdzi ieHTTPHeaders dostpny pod adresem http://
www.blunck.info/iehttpheaders.html. Na rysunku 5.1 pokazano przykadowe nagwki dla przegldarki FireFox podczas dostpu do strony macierzystej PHP.

Tworzenie plikw cookie


<?php
setcookie('version', phpversion());
?>
Prba wysania pliku cookie.

Do tworzenia plikw cookie suy funkcja PHP setcookie(). Funkcja przyjmuje nastpujce parametry (tylko

pierwszy z nich jest obowizkowy):


1. Nazwa pliku cookie.

ZAPAMITYWANIE USTAWIE UYTKOWNIKW

Rysunek 5.1. Pliki cookie s ustawiane w nagwkach HTTP

ROZDZIA 5

Tworzenie plikw cookie

2. Warto pliku cookie.


3. Data wanoci (w formacie uniksowego znacznika czasu).
4. Katalog na serwerze WWW, z ktrego mona uzyska
dostp do pliku cookie.
5. Domena, z ktrej mona uzyska dostp do pliku cookie.
163

ROZDZIA 5

ZAPAMITYWANIE USTAWIE UYTKOWNIKW

Odczytywanie plikw cookie

6. Informacja, czy plik cookie mona przesya tylko za


pomoc bezpiecznych pocze HTTPS (SSL).
W kodzie zamieszczonym na pocztku tego podrozdziau
ustawiono prosty plik cookie sesji z wartoci w postaci
biecej wersji PHP.
Na rysunku 5.2 pokazano okno z ostrzeeniem wywietlane w przegldarce Firefox. Bez trudu mona odczyta
nazw pliku cookie i jego warto.

Rysunek 5.2. Firefox otrzymuje plik cookie i wywietla pytanie


do uytkownika o to, co z nim zrobi

Odczytywanie plikw cookie


Wszystkie pliki cookie, do ktrych serwer ma dostp (nie
musz to by wszystkie pliki cookie, ktre s zapisane
w przegldarce!) s dostpne w tablicy superglobalnej
164

$_COOKIE. W kodzie zaprezentowanym poniej wszystkie

pliki cookie s odczytywane w ptli foreach i wysyane


do klienta w postaci tabeli HTML.

Czytanie plikw cookie (getcookie.php)

OSTRZEENIE
Poniewa pliki cookie s przesyane jako nagwki HTTP,
musz by utworzone przed wysaniem wyjcia HTML (chyba
e korzystamy z buforowania wynikw). W innym przypadku
uzyskamy komunikat o bdzie podobny do tego, ktry pokazano na rysunku 5.3.

ZAPAMITYWANIE USTAWIE UYTKOWNIKW

<table>
<?php
foreach ($_COOKIE as $name => $value) {
printf('<tr><td>%s</td><td>%s</td></tr>',
htmlspecialchars($name),
htmlspecialchars($value));
}
?>
</table>

ROZDZIA 5

Odczytywanie plikw cookie

Rysunek 5.3. Pliki cookie trzeba przesa przed wysaniem


zawartoci HTML
165

ROZDZIA 5

ZAPAMITYWANIE USTAWIE UYTKOWNIKW


166

Pozbywanie si magicznych cudzysoww z plikw cookie

UWAGA
Zazwyczaj interpreter PHP automatycznie unieszkodliwia znaki
specjalne w wartociach plikw cookie poprzez poprzedzenie
ich znakami lewego ukonika (szczeglnie w przypadku przekazywania plikw cookie poprzez URL). Jednak poczwszy od
PHP 5 mona to robi rcznie, poprzez wysanie surowych
danych pliku cookie. Aby to uczyni, naley przekaza do
funkcji setrawcookie() te same parametry, ktre byy
przekazane do funkcji setcookie(). Obie funkcje dziaaj
podobnie. Rnica polega na tym, e pierwsza z nich nie koduje wartoci pliku cookie. Aby j zakodowa, naley rcznie
wywoa funkcj urlencode().

Pozbywanie si magicznych
cudzysoww (apostrofw)
z plikw cookie
Pozbywanie si magicznych cudzysoww z plikw cookie

Magiczne cudzysowy (apostrofy), ktre opisano i wyklto


w poprzednim rozdziale, dotycz rwnie plikw cookie,
poniewa to rwnie s dane pochodzce od klientw. Tak
wic, jeli ustawiono opcj magic_quotes na warto on,
znaki apostrofw i cudzysoww bd poprzedzane znakiem lewego ukonika. Aby pozby si ukonikw, mona wykorzysta poniszy kod. Podobny kod zastosowano
w poprzednim rozdziale do usunicia ukonikw z danych
formularzy (danych GET i POST).

Jeli ustawiono opcj magic_quotes, funkcja stripslashes() bdzie wywoywana rekurencyjnie dla wszystkich
danych w tablicy $_COOKIE.

if (get_magic_quotes_gpc()) {
$_COOKIE = stripCookieSlashes($_COOKIE);
}
?>

Usuwanie magicznych cudzysoww (apostrofw) z plikw cookie


(stripCookieSlashes.inc.php)

Skrypt stripCookieSlashes.inc.php naley wczy do wszystkich skryptw PHP, ktre odczytuj pliki cookie za pomoc nastpujcej instrukcji:
require_once 'stripCookieSlashes.inc.php';

Ustawianie daty wanoci


wzgldem innej daty

ZAPAMITYWANIE USTAWIE UYTKOWNIKW

<?php
function stripCookieSlashes($arr) {
if (!is_array($arr)) {
return stripslashes($arr);
} else {
return array_map('stripCookieSlashes', $arr);
}
}

ROZDZIA 5

Ustawianie daty wanoci wzgldem innej daty

Data wanoci pliku cookie jest przekazywana za pomoc


trzeciego parametru funkcji setcookie(). Jest to liczba
cakowita, dlatego trzeba uy uniksowego znacznika czasu.

167

ROZDZIA 5

ZAPAMITYWANIE USTAWIE UYTKOWNIKW


168

Ustawianie daty wanoci wzgldem innej daty

W rozdziale 3., Daty i godziny, zamieszczono sporo


informacji dotyczcych sposobu wykorzystania tego rodzaju danych.
<?php
setcookie('version', phpversion(), time() +
21*24*60*60);
?>
Prba wysania pliku cookie.

Ustawianie daty wanoci pliku cookie wzgldem innej daty


(setcookie-expiry.php)

Zwykle lepszym pomysem jest ustawienie daty wanoci


pliku cookie wzgldem innej daty (za trzy tygodnie), ni
podawanie daty konkretnej (koniec maja 2006). W przypadku uycia dat bezwzgldnych skrypt trzeba regularnie
modyfikowa, poniewa czsto data wyganicia wanoci
nadchodzi bardzo szybko. Ustawianie czasu wanoci na
bardzo odlega dat w przyszoci, na przykad w roku
2030, uwaa si za dziaanie nieprofesjonalne. Klient, ktry
otrzyma taki plik cookie, najprawdopodobniej w roku
2030 ju nie bdzie si logowa na serwerze.
Z tych wzgldw warto stosowa daty wzgldem innych
dat. Funkcja PHP date() pobiera warto uniksowego
znacznika czasu dla daty biecej. Do tej wartoci wystarczy doda liczb sekund, przez jak plik cookie ma
by wany. Kod zaprezentowany na poprzednim listingu
ustawia plik cookie, ktry bdzie wany przez trzy tygodnie.

Ustawianie daty wanoci


specyficznej dla klienta

ROZDZIA 5

Ustawianie daty wanoci specyficznej dla klienta

setcookie('version', phpversion(),
$_GET['time'] + 21*24*60*60)

<?php
if (isset($_GET['time']) && is_int($_GET['time']))
{
setcookie('version', phpversion(),
$_GET['time'] + 21*24*60*60);
} else {
setcookie('version', phpversion(),
time() + 21*24*60*60);
}
?>
Prba wysania pliku cookie.

ZAPAMITYWANIE USTAWIE UYTKOWNIKW

Naley pamita, e decyzja dotyczce tego, kiedy plik


cookie traci wano, jest podejmowana po stronie klienta
i z wykorzystaniem ustawie daty i godziny klienta. Jeli
zatem data klienta jest ustawiona nieprawidowo (czego
po stronie serwera nie mona kontrolowa), pliki cookie
bd traciy wano wczeniej lub pniej ni si spodziewamy. Nie warto zatem ustawia plikw cookie, ktre
bd wane przez godzin. Nasze plany mog zniweczy
tak bahe sytuacje jak zmiana czasu z zimowego na letni.

Ustawianie pliku cookie z okrelon dat wanoci (setcookie-specific.php)

Wystarczy jednak odrobina kodu w JavaScript, aby unikn


opisanej puapki. Kod zamieszczony na poniszym listingu
to dziaajcy po stronie klienta skrypt JavaScript, ktry
sprawdza biec godzin wyraon jako uniksowy znacznik
169

ROZDZIA 5

ZAPAMITYWANIE USTAWIE UYTKOWNIKW

Usuwanie plikw cookie

czasu i wysya j do dziaajcego na serwerze skryptu setcookie-specific.php. Najwaniejsza rnica pomidzy funkcj PHP time() a metod getTime() jzyka JavaScript
polega na tym, e ta druga zwraca liczb milisekund, jakie
upyny od pnocy 1 stycznia 1970 roku, natomiast pierwsza liczb sekund. Z tego powodu warto otrzyman ze
skryptu JavaScript naley najpierw podzieli przez 1000
i zaokrgli w d do caoci.
Kod skryptu setcookie-specific.php zamieszczono na pocztku tego podrozdziau. Przesyana warto jest wykorzystywana jako podstawa obliczenia relatywnej daty wanoci
pliku cookie.
<script language = "JavaScript"
type="text/javascript><!var epoche = (new Date() - getTime();
epoche = Math.floor(epoche/1000);
location.replace("setcookie-specific.php?time="
+ epoche);
//-></script>

Usuwanie plikw cookie


setcookie('version', '', time() - 10*365*24*60*60);

Intuicyjnym sposobem usunicia pliku cookie jest ustawienie jego wartoci na pusty cig znakw. Ta operacja
nie powoduje jednak usunicia pliku cookie. Plik w dalszym cigu istnieje, cho ju nie ma ustawionej wartoci.
Lepszym sposobem jest ponowne przesanie tego samego
170

Rysunek 5.4. Plik cookie bdzie usunity (jeli uytkownik go


zaakceptuje)

ZAPAMITYWANIE USTAWIE UYTKOWNIKW

pliku cookie z dat wanoci w przeszoci. Take w tym


przypadku trzeba uwzgldni nieprawidowe ustawienia
czasu lokalnego, a zatem naley wybiera bardzo odlege
daty utraty wanoci, na przykad 10 lat wczeniej. Sposb
ten zaimplementowano poniej, gdzie usunito plik cookie
ustawiony w kodzie pokazanym na poprzednim listingu.
W tej implementacji poczono obie metody ustawiono
warto na pusty cig znakw i dat wyganicia pliku
cookie w przeszoci. Wynik dziaania skryptu pokazano
na rysunku 5.4 przegldarka prbuje usun plik cookie
poprzez ustawienie daty jego wyganicia na okrelony
czas (w przeszoci, a zatem plik cookie przestaje istnie).

ROZDZIA 5

Usuwanie plikw cookie

<?php
setcookie('version', '', time() 10*365*24*60*60);
?>
Prba usunicia pliku cookie.

Usuwanie plikw cookie (deletecookie.php)

171

ROZDZIA 5

ZAPAMITYWANIE USTAWIE UYTKOWNIKW

Udostpnianie plikw cookie dla wielu domen

OSTRZEENIE
Jeli sprbujemy ustawi dat utraty wanoci na 0, PHP pominie ten parametr, a zatem ten sposb nie zadziaa. Trzeba
uy argumentu o dodatniej wartoci na przykad 1.

Udostpnianie plikw cookie


dla wielu domen
setcookie('version', phpversion(), 0,
'.przyklad.com');

Czci nagwka Set-Cookie wysyanego przez serwer


jest domena, ktra ma dostp do tego pliku cookie. Jeli
warto ta nie zostanie okrelona jawnie, domylnie przyjmuje si domen, z ktrej wysano plik cookie. Prba
ustawienia tej wartoci na cakiem inn domen na przykad serwera reklam (tzw. pliki cookie firm zewntrznych,
uywane w celu wygenerowania profilu uytkownika)
nie zawsze zadziaa, poniewa wiele przegldarek umoliwia zablokowanie takiej moliwoci (na rysunku 5.5
wida, e tak moliwo miay ju stare przegldarki
Netscape 4.x).
<?php
setcookie('version', phpversion(), 0,
'.przyklad.com');
?>
Prba przesania pliku cookie.

Ustawianie domeny dla pliku cookie (setcookie-domain.php)

172

W niektrych przypadkach istnieje potrzeba, aby pliki cookie dziaay w kilku domenach zewntrznych lub poddomenach, na przykad www.przyklad.com, sklep.przyklad.com
i ssl.przyklad.com. Sytuacja dotyczy duych witryn WWW
z wieloma poddomenami, takich jak Amazon czy eBay.
Witryny te wymagaj obsugi dla wszystkich domen najwyszego poziomu. Aby to byo moliwe, trzeba ustawi
domen pliku cookie czwarty parametr funkcji setcookie(). Jest jednak pewien kopot: nazwy domen s
prawidowe, o ile zawieraj dwie kropki. Jeli zatem ustawimy domen na .przyklad.com, do pliku cookie bd

ZAPAMITYWANIE USTAWIE UYTKOWNIKW

Rysunek 5.5. Nawet w przegldarce Netscape 4.x mona


zablokowa pliki cookie, ktre pochodz z innych domen

ROZDZIA 5

Udostpnianie plikw cookie dla wielu domen

173

ROZDZIA 5

ZAPAMITYWANIE USTAWIE UYTKOWNIKW

Sprawdzanie, czy klient obsuguje pliki cookie

miay dostp wszystkie domeny trzeciego poziomu domeny


przyklad.com. Jest jednak jedno ale. Strony umieszczone
w domenie http://przyklad.com nie bd miay dostpu do
tego pliku cookie. Mona zatem sprbowa ustawi domen na przyklad.com, ale to nie jest zgodne ze specyfikacj
i moe nie zadziaa w niektrych przegldarkach.

Sprawdzanie, czy klient


obsuguje pliki cookie
$test_temp = isset($_COOKIE['test_temp']) ?
'obsuguje' : 'nie obsuguje';
$test_persist = isset($_COOKIE['test_persist']) ?
'obsuguje' : 'nie obsuguje';

Pamitacie, w jaki sposb s przesyane pliki cookie? Najpierw serwer przesya plik cookie do klienta w odpowiedzi
HTTP. W nastpnym daniu, jeli uytkownik zaakceptuje plik cookie, klient przesya go z powrotem na
serwer. Z tego powodu wywoanie funkcji setcookie()
i pniejsze sprawdzenie zawartoci tablicy $_COOKIE nie
zadziaa. Trzeba zaczeka na kolejne danie HTTP.
<?php
if (isset($_GET['step']) && $_GET['step'] == '2') {
$test_temp = isset($_COOKIE['test_temp']) ?
'obsuguje' : 'nie obsuguje';
$test_persist = isset($_COOKIE['test_persist']) ?
'obsuguje' : 'nie obsuguje';
setcookie('test_temp', '', time() - 365*24*60*60);
setcookie('test_persist', '', time() 365*24*60*60);

174

Testowanie konfiguracji plikw cookie przegldarki (cookietest.php)

Mona jednak skorzysta z funkcji header() i wymusi


utworzenie drugiego dania klienta. W pierwszym daniu ustawiamy plik cookie, w drugim sprawdzamy, czy
operacja zakoczya si sukcesem.
W zaprezentowanym powyej kodzie ustawiono dwa pliki
cookie jeden tymczasowy i drugi trway poniewa
niektre przegldarki mona tak skonfigurowa, e jeden
typ plikw cookie bdzie akceptowany, a drugi nie. Nastpnie, aby sprawdzi ustawienie wszystkich plikw cookie, wystarczy wykona przekierowanie za pomoc funkcji
header() oraz nagwka HTTP Location.

ZAPAMITYWANIE USTAWIE UYTKOWNIKW

echo "Przegldarka $test_temp tymczasowe pliki


cookie.<br />";
echo "Przegldarka $test_persist trwae pliki
cookie.";
} else {
setcookie('test_temp', 'ok');
setcookie('test_presist', 'ok', time() +
14*24*60*60);
header('Location: ' .
nl2br($_SERVER['PHP_SELF']) . '?step=2');
}
?>

ROZDZIA 5

Sprawdzanie, czy klient obsuguje pliki cookie

Oczywicie trzeba tak skonfigurowa przegldark, aby


w momencie przesania pliku cookie by wywietlany komunikat znacznie uatwia to debugowanie.

175

ROZDZIA 5

Zapisywanie wielu danych w jednym pliku cookie

Zapisywanie wielu danych


w jednym pliku cookie

ZAPAMITYWANIE USTAWIE UYTKOWNIKW

setcookie('cookiedata', serialize($cookiedata)

176

Zazwyczaj w pliku cookie jest ustawiona jedna warto


cig znakw. Z tego powodu, aby zapisa za pomoc
plikw cookie wiele danych, trzeba uy wielu plikw
cookie. Takie dziaanie stwarza jednak pewne problemy
na przykad z powodu ograniczenia 20 plikw cookie
na domen. Z tego wzgldu w niektrych przypadkach
ma sens zapisywanie wielu danych w jednym pliku cookie.
Do tego przydaj si tablice.
Wartociami plikw cookie mog by jednak wycznie
cigi znakw. Z tego powodu tablic trzeba przeksztaci
na cig znakw za pomoc funkcji serialize(). Pniej
mona j przeksztaci z powrotem na tablic za pomoc
funkcji unserialize().
<?php
require_once 'stripCookieSlashes.inc.php';
function setCookieData($arr) {
$cookiedata = getAllCookieData();
if ($cookiedata == null) {
$cookiedata = array();
}
foreach ($arr as $name => $value) {
$cookiedata[$name] = $value;
}
setcookie('cookiedata',
serialize($cookiedata),

time() + 30*24*60*60);
}

function getCookieData($name) {
$cookiedata = getAllCookieData();
if ($cookiedata != null &&
isset($cookiedata[$name])) {
return $cookiedata[$name];
}
}
return '';
}
?>

Biblioteka pomocnicza do zapisywania wielu danych w jednym pliku cookie


(getCookieData.inc.php)

Do tego celu mona napisa bibliotek podobn do tej,


ktr wykorzystywalimy w poprzednim rozdziale do zapisywania danych formularza w pliku cookie. Jeden plik
cookie o nazwie cookiedata zawiera wszystkie wartoci zapisane w postaci tablicy asocjacyjnej. Funkcja getCookieData() zwraca jedn warto, natomiast setCookieDate()
pobiera tablic i zapisuje jej zawarto do pliku cookie.
Kompletny kod rdowy tej biblioteki pokazano na powyszym listingu.

ZAPAMITYWANIE USTAWIE UYTKOWNIKW

function getAllCookieData() {
if (isset($_COOKIE['cookiedata'])) {
$formdata = $_COOKIE['cookiedata'];
if ($formdata != '') {
return unserialize($formdata);
} else {
return array();
}
} else {
return null;
}
}

ROZDZIA 5

Zapisywanie wielu danych w jednym pliku cookie

177

ROZDZIA 5

ZAPAMITYWANIE USTAWIE UYTKOWNIKW


178

Zapisywanie ustawie jzykowych uytkownika

Z kolei na listingu zamieszczonym poniej wykorzystano


zdefiniowan bibliotek do zaimplementowania testu dla
plikw cookie znanych z poprzedniego podrozdziau.
<?php
require_once 'getCookieData.inc.php';
if (isset($_GET['step']) && $_GET['step'] == '2')
{
$test = (getCookieData('test') == 'ok') ?
'obsuguje' : 'nie obsuguje';
echo "Przegldarka $test pliki cookie.";
} else {
setCookieData(array('test' => 'ok'));
header("Location:
{$_SERVER['PHP_SELF']}?step=2");
}
?>

Zapisywanie ustawie
jzykowych uytkownika
setcookie('lang', $_SERVER['PHP_SELF'], time() +
30*24*60*60, '/')

Bardzo czsto strony WWW obsuguj wiele jzykw.


Zazwyczaj s one tak zorganizowane, e kada zlokalizowana cz witryny jest zapisana w osobnym katalogu, na
przykad w nastpujcej konfiguracji:

wersja dla jzyka angielskiego jest zapisana w katalogu en,

wersja dla jzyka hiszpaskiego jest zapisana w katalogu es,

wersja dla jzyka francuskiego jest zapisana w katalogu fr,

wersja dla jzyka polskiego jest zapisana w katalogu pl.

ROZDZIA 5

Zapisywanie ustawie jzykowych uytkownika

Jzyk uytkownika mona wykry na kilka sposobw:


prbujc powiza adres IP klienta z okrelonym regionem geograficznym,

odczytujc nagwek HTTP Accept-Language, z ktrego mona si dowiedzie, jakie jzyki s preferowane,

zadajc uytkownikowi pytanie.

Chocia kada z tych metod jest w jakim stopniu skuteczna, ostatnia (lub kombinacja kilku) jest uwaana za najbardziej przyjazn dla uytkownika. Trzeba zatem zdefiniowa
stron macierzyst zawierajc cza do wszystkich dostpnych wersji jzykowych. Wystarczy prosty jzyk HTML:
<a
<a
<a
<a

href="en/index.php">English version</a><br />


href="es/index.php">Versin espaol</a><br />
href="fr/index.php">Versione franaise</a><br />
href="pl/index.php">Wersja polska</a>

Strona macierzysta zawiera cza do rnych wersji jzykowych (multilingual.php


fragment)

ZAPAMITYWANIE USTAWIE UYTKOWNIKW

W katalogu dla kadego jzyka znajduje si skrypt index.php


napisany w okrelonej wersji jzykowej. W tym pliku przechowywany jest kod z listingu zamieszczonego na pocztku
tego podrozdziau. Instrukcja sprawdza, czy ju ustawiono
plik cookie dla wersji jzykowej, a jeli nie ustawia plik
cookie dla biecego katalogu (odczytanego za pomoc
odwoania do elementu $_SERVER['PHP_SELF']).
179

ROZDZIA 5

ZAPAMITYWANIE USTAWIE UYTKOWNIKW


180

Zapisywanie ustawie jzykowych uytkownika

<?php
if (!isset($_COOKIE['lang']) ||
$_COOKIE['lang'] != $_SERVER['PHP_SELF']) {
setcookie('lang', $_SERVER['PHP_SELF'],
time() + 30*24*60*60, '/');
}
?>

Zapisywanie informacji o biecym katalogu w pliku cookie


(savelanguage.inc.php)

UWAGA
Jest bardzo istotne, aby ustawi ciek pliku cookie na
gwny katalog serwera WWW. W innym przypadku wartoci domyln cieki bdzie katalog biecy i plik bdzie
mg by odczytany tylko w katalogu biecym i jego podkatalogach. Nie bdzie go mona go odczyta ze strony macierzystej.
Na koniec, na stronie macierzystej trzeba sprawdzi, czy
ustawiono plik cookie, a jeli tak, przekierowa uytkownika na stron zawierajc odpowiedni wersj jzykow.
W tym celu na pocztku skryptu multilingual.php trzeba
wprowadzi nastpujcy kod:
<?php
if (isset($_COOKIE['lang']) && $_COOKIE['lang']
!= '') {
header("Location: {$_COOKIE['lang']}");
}
?>

Sesje

Protok HTTP nie zawiera adnego mechanizmu obsugi


sesji, poniewa jest bezstanowy. PHP zawiera jednak wbudowan obsug sesji, dziki czemu skorzystanie z nich jest
stosunkowo proste.
Po utworzeniu sesji PHP generuje jej identyfikator w postaci dugiego cigu znakw. Nastpnie tworzy zapis w pliku
lub bazie danych dotyczcy okrelonej sesji. Po wykonaniu
tych operacji aplikacja PHP moe zapisywa dane w sesji.
Dane te trafiaj do pliku sesji bd do bazy danych (rzadziej dane sesji s zapisywane w pamici wspdzielonej).
Zatem jedynym elementem, ktry musi by przekazywany
pomidzy klientem a serwerem jest identyfikator sesji.
Wszystkie pozostae dane zwizane z sesj s przechowywane na serwerze. Dziki temu w czu nie s niepotrzebnie
przesyane istotne dane.

ZAPAMITYWANIE USTAWIE UYTKOWNIKW

Sesja to nic innego jak wizyta uytkownika na stronie


WWW. Uytkownik klika jakie cza, przeglda niektre
strony i wychodzi. Dziaania uytkownika w witrynie
WWW definiuj sesj. Jeli uytkownik nie zada danych
z witryny WWW przez pewien czas, na przykad 20 minut, sesja koczy si.

ROZDZIA 5

Sesje

Konfiguracja mechanizmu sesji jzyka PHP jest w caoci


zapisana w sekcji [session] pliku konfiguracyjnego php.ini.
Domylne ustawienia nie pasuj do wszystkich zastosowa, dlatego w kolejnych podrozdziaach opisano kilka
moliwych konfiguracji.
181

ROZDZIA 5

ZAPAMITYWANIE USTAWIE UYTKOWNIKW

Gdzie naley zapisywa sesje?

Gdzie naley zapisywa sesje?


Zazwyczaj dane sesji s zapisywane w plikach. Lokalizacj
tych plikw ustawia si za pomoc dyrektywy pliku php.ini
session.save_path. Oczywicie katalog ustawiony za pomoc tej dyrektywy musi po pierwsze istnie, a po drugie
proces PHP (zwykle proces serwera WWW) musi mie
w nim uprawnienia odczytu i zapisu. W innym przypadku danych sesji nie mona zapisa.
Jednak w przypadku duej liczby uytkownikw, a co za
tym idzie duej liczby sesji, interpreter PHP nie powinien
umieszcza wszystkich plikw sesji w jednym katalogu, poniewa moe to wpyn na znaczne obnienie wydajnoci. Ponisza instrukcja umoliwia przenoszenie danych
sesji do wielu podkatalogw:
session.save_path = "n;/tmp"

Skorzystanie z tej dyrektywy spowoduje utworzenie podkatalogw w katalogu /tmp do 5 poziomw w gb. Aby
mechanizm sesji PHP mg zapisywa dane w podkatalogach, trzeba je wczeniej utworzy. Do tego celu suy
skrypt mod_files.sh w katalogu ext/sessions.
Oczywicie prawo do odczytywania tego katalogu powinien posiada tylko serwer WWW. W innym przypadku
inni uytkownicy systemu mogliby odczytywa informacje o sesji potencjalnie zawierajce wraliwe dane.

182

W jaki sposb
zachowa stan sesji?

Najprociej mona zaimplementowa ten mechanizm za


pomoc plikw cookie. PHP przesya do klienta plik cookie
o nazwie PHPSESSID (nazw mona zmieni za pomoc dyrektywy pliku php.ini session.name). Aby byo to moliwe, naley ustawi nastpujc dyrektyw pliku php.ini:
session.use_cookies = 1

Co jednak zrobi, jeli uytkownik wyczy obsug plikw cookie? W takim przypadku mona skorzysta z innego mechanizmu. W tym celu naley ustawi nastpujc
dyrektyw:
session.use_trans_sid = 0

W tym przypadku PHP automatycznie ustawia tryb, w ktrym identyfikator sesji jest doczany do wszystkich adresw URL. Takie rozwizanie moe powodowa pewne
zagroenie (na przykad modyfikowanie sesji ang. session
fixation, lub przechwytywanie sesji ang. session hijacking), ale jest do praktyczne. Wykorzystuj je wszystkie znane witryny e-commerce, na przykad Amazon. Jeli
odwiedzimy ich witryn WWW i zaadujemy stron, identyfikator sesji zostanie automatycznie doczony na kocu
adresu URL.

ZAPAMITYWANIE USTAWIE UYTKOWNIKW

Identyfikator sesji musi by przesany do przegldarki


w kadej odpowiedzi, a co waniejsze musi by przesany z powrotem na serwer wraz z kadym daniem.

ROZDZIA 5

W jaki sposb zachowa stan sesji?

183

ROZDZIA 5

ZAPAMITYWANIE USTAWIE UYTKOWNIKW

Aktywacja sesji

Aby mona byo skorzysta z ustawienia session.user_


trans_sid, PHP musi by skompilowane z przecznikiem -enable-trans-sid. Opcja ta jest automatycznie
wczona dla binarnych dystrybucji przeznaczonych dla
systemw Windows i Mac OS X.
Mona rwnie zezwoli na przekazywanie w adresach
URL tylko plikw cookie, bez identyfikatorw sesji. Do
tego suy nastpujca dyrektywa pliku php.ini:
session.use_only_cookies = 1

UWAGA
Przekazywanie identyfikatorw sesji w adresach URL w zasadzie jest ze, poniewa odwiedzajcy mog zapisywa je
w postaci zakadek, niektre wyszukiwarki nie uwzgldniaj
witryn, w ktrych stosuje si t technik itd. W kadej witrynie e-commerce (a take w wikszoci innych witryn) trzeba
jednak wzi pod uwag, e niektrzy odwiedzajcy (potencjalni klienci!) nie wcz obsugi plikw cookie. W takim
przypadku sesje gwarantuj wygodny sposb pokonania tego
ograniczenia.

Aktywacja sesji
session_start()

Korzystanie z mechanizmw zarzdzania sesjami zawsze


wymaga zasobw, a w zwizku z tym wie si z obnieniem wydajnoci. Dlatego wanie sesje trzeba aktywowa.
184

Poniewa operacja ta moe wymaga przesania plikw


cookie, trzeba to zrobi przed wysaniem do klienta zawartoci HTML. Mona to zrobi na dwa sposoby:
globalna aktywacja sesji za pomoc dyrektywy pliku
php.ini session.auto_start = 1,

aktywacja sesji na poziomie skryptu, za pomoc funkcji


session_start().

Z punktu widzenia wydajnoci druga opcja jest lepsza.


<?php
session_start();
echo 'Sesje aktywowano.';
?>

Aktywacja sesji (session_start.php)

Czytanie i zapisywanie sesji


<?php
session_start();
echo 'Sesje uaktywniono.<br />';
$_SESSION['version'] = phpversion();
echo 'Dane sesji zapisano.<br />';
echo "Dane sesji zostay odczytane:
{$_SESSION['version']} .";
?>

ZAPAMITYWANIE USTAWIE UYTKOWNIKW

ROZDZIA 5

Czytanie i zapisywanie sesji

Dostp do wszystkich danych sesji w skrypcie PHP mona uzyska za pomoc tablicy $_SESSION. Poniewa dane
s zapisane po stronie serwera, mona zapisa dane sesji
i odczyta je ju w nastpnej instrukcji PHP bez koniecznoci transmisji, tak jak to byo w przypadku plikw cookie.
185

ROZDZIA 5

ZAPAMITYWANIE USTAWIE UYTKOWNIKW

Zamykanie sesji

Wystarczy pamita o wywoaniu funkcji session_start().


Potem mona korzysta z tablicy $_SESSION. Kod zamieszczony na listingu na pocztku tego podrozdziau tworzy plik sesji pokazany na rysunku 5.6.

Rysunek 5.6. Zawarto pliku sesji utworzonego przez kod


pokazany na poprzednim listingu

Zamykanie sesji
session_destroy()

W niektrych przypadkach, na przykad kiedy uytkownik


si wyloguje, wszystkie dane sesji naley usun, a sesj zamkn. Oczywicie mona przetworzy tablic $_SESSION
w ptli foreach i ustawi kad z wartoci na pusty cig
znakw, ale istnieje szybszy sposb wystarczy wywoa
funkcj session_destroy(). Po wykonaniu tej funkcji,
tak jak wskazuje nazwa (destroy niszczy), wszystkie
dane w biecej sesji zostan zniszczone.
<?php
session_start();
echo 'Przed: <pre>';
print_r($_SESSION);
echo '</pre>Po: <pre> ';
session_destroy();

186

print_r($_SESSION);
echo '</pre>';
?>

Usuwanie wszystkich danych sesji (session_destroy.php)

session_regenerate_id()

Jednym ze znanych atakw przeciwko witrynom WWW


zabezpieczonych za pomoc sesji jest przechwycenie identyfikatora sesji uytkownika (na przykad w wyniku analizy
zapisw HTTP_REFERER w daniach HTTP), a nastpnie
wykorzystanie go w celu podszycia si pod niego. Z takimi atakami trudno si walczy, mona jednak utrudni
ycie napastnikom, zmieniajc identyfikator sesji kadorazowo, kiedy co wanego si zmienia, na przykad gdy
uytkownik si zaloguje. Przykadowo w witrynie Amazon
uytkownicy, ktrzy zostali wczeniej uwierzytelnieni za
pomoc pliku cookie, gdy chc co zamwi, musz si ponownie zalogowa.

ZAPAMITYWANIE USTAWIE UYTKOWNIKW

Modyfikacje
identyfikatora sesji

ROZDZIA 5

Modyfikacje identyfikatora sesji

<?php
ob_start();
session_start();
echo 'Stary: ' . session_id();
session_regenerate_id();
echo '<br />Nowy: ' . session_id();
ob_end_flush();
?>

Modyfikacja identyfikatora sesji (session_regenerate_id.php)

187

ROZDZIA 5

ZAPAMITYWANIE USTAWIE UYTKOWNIKW

Tworzenie dynamicznych czy z obsug sesji

W tym przypadku funkcja session_regenerate_id()


modyfikuje biecy identyfikator sesji, ale pozostawia zapisane w niej dane bez zmian. Pokazano to w zamieszczonym
wczeniej kodzie, gdzie za pomoc funkcji session_id()
odczytano stary i biecy identyfikator sesji. Przykadowy
wynik dziaania tego skryptu pokazano na rysunku 5.7.

Rysunek 5.7. Dwa identyfikatory sesji: stary i nowy

UWAGA
W tym kodzie wykorzystano buforowanie wynikw funkcje ob_start() i ob_end_flush() poniewa funkcj
session_regenerate_id() trzeba wywoa przed wysaniem do klienta wyniku HTML.

Tworzenie dynamicznych czy


z obsug sesji
$name = urlencode(session_name());
$id = urlencode(session_id());
echo "<a href=\"page.php?$name=$id\">dynamiczne
cze</a>";

188

Zastosowanie ustawienia session.use_trans_sid w celu


automatycznej aktualizacji wszystkich czy w taki sposb,
by zawieray identyfikatory sesji, to dobry pomys, jednak
sposb ten nie zadziaa, jeli cza bd generowane automatycznie przez PHP. W PHP istniej jednak dwie funkcje,
ktre dostarczaj wszystkich potrzebnych informacji:
session_id()

zwraca nazw sesji,

zwraca biecy identyfikator sesji.

Tak wic kod zamieszczony na pocztku tego podrozdziau


tworzy dynamiczne cze zawierajce informacje o sesji.
W ten sposb programista moe tworzy dynamiczne cza
z obsug sesji.
Oto przykadowy wynik dziaania zamieszczonego wyej
kodu:
<a href="page.php?PHPSESSID=2600b43e0fecb
4d5a990bf848289a8fe">dynamiczne cze</a>

WSKAZWKA
Kiedy korzystamy z formularzy HTML, PHP automatycznie
docza identyfikator sesji do atrybutu action formularza.
Jednak, aby wykorzysta formularze dynamiczne, mona doda ukryte pole zawierajce informacje o sesji:

ZAPAMITYWANIE USTAWIE UYTKOWNIKW

session_name()

ROZDZIA 5

Tworzenie dynamicznych czy z obsug sesji

<?php
$name = htmlspecialchars(session_name());
$id = htmlspecialchars(session_id());
echo "<input type=\"hidden\" name=\"$name\"
value=\"$id\" />";
?>

189

ROZDZIA 5

ZAPAMITYWANIE USTAWIE UYTKOWNIKW

Implementacja wasnego mechanizmu zarzdzania sesjami

Implementacja wasnego
mechanizmu zarzdzania
sesjami
session_set_save_handler(
'sess_open', 'sess_close', 'sess_read',
'sess_write', 'sess_destroy', 'sess_gc');

Istniej powody, dla ktrych nie powinno si zapisywa


danych sesji w plikach. Wydajno to jedno, a bezpieczestwo to drugie. Alternatywnie mona zapisywa dane sesji
w bazach danych. Aby mona to byo zrobi, naley utworzy tabel bazy danych sessiondata z trzema kolumnami
(ich nazwy mog by rne, jednak naley je konsekwentnie
stosowa w kodzie zaprezentowanym na listingach zamieszczonych poniej):

kolumna id (klucz gwny) jest typu VARCHAR(32)


i zawiera identyfikator sesji,

kolumna data jest typu TEXT i zawiera dane sesji,

kolumna access jest typu VARCHAR(14) i zawiera znacznik czasu ostatniego dostpu do danych sesji.

Nie ma znaczenia, jak baz danych wykorzystamy. W tym


podrozdziale wykorzystano baz MySQL i nowe rozszerzenie PHP5 mysqli. Bez trudu mona jednak tak zmodyfikowa kod, aby dziaa rwnie z innymi bazami danych
(wicej informacji dotyczcych wykorzystania rnych baz
danych w PHP mona znale w rozdziale 7.).
190

Funkcj PHP session_set_save_handler() mona wykorzysta do zdefiniowania wasnych funkcji dla szeciu
operacji wewntrznie wykonywanych przez PHP:
otwierania sesji,

zamykania sesji,

odczytywania zmiennej sesji,

zapisywania zmiennej sesji,

niszczenia sesji,

porzdkowania (tzw. odmiecania ang. garbage


collection polegajcego, na przykad, na usuwaniu
starych danych sesji z bazy danych).

Kod dla wszystkich tych szeciu operacji, ktry odczytuje


i zapisuje dane sesji do i z bazy danych MySQL, zamieszczono na poniszym listingu. Aby z niego skorzysta, trzeba zainstalowa PHP 5 i odpowiednio ustawi
parametry poczenia (serwer, nazw uytkownika, haso).
Nastpnie naley wczy kod zamieszczony na poniszym
listingu za pomoc funkcji require_once. Po wykonaniu
tych operacji mona wykorzystywa sesje w standardowy
sposb. Od tego momentu PHP bdzie zapisywa informacje dotyczce sesji w bazie danych, a nie w plikach.

ZAPAMITYWANIE USTAWIE UYTKOWNIKW

ROZDZIA 5

Implementacja wasnego mechanizmu zarzdzania sesjami

<?php
$GLOBALS['sess_server'] = 'localhost';
$GLOBALS['sess_db'] = 'sessions';
$GLOBALS['sess_username'] = 'user';
$GLOBALS['sess_password'] = 'pass';
function sess_open() {

191

ROZDZIA 5

Implementacja wasnego mechanizmu zarzdzania sesjami

$GLOBALS['sess_mysqli'] = mysqli_connect(
$GLOBALS['sess_server'],
$GLOBALS['sess_username'],
$GLOBALS['sess_password']
);
mysqli_select_db($GLOBALS['sess_mysqli'],
$GLOBALS['sess_db']);

ZAPAMITYWANIE USTAWIE UYTKOWNIKW

}
function sess_close() {
mysqli_close($GLOBALS['sess_mysqli']);
}
function sess_read($id) {
$result = mysqli_query(
$GLOBALS['sess_mysqli'],
sprintf('SELECT data FROM sessiondata WHERE id
= \'%s\'',
mysqli_real_escape_string($GLOBALS['sess_mysqli'],
$id))
);
if ($row = mysqli_fetch_object($result)) {
$ret = $row->data;
mysqli_query(
$GLOBALS['sess_mysqli'],
sprintf('UPDATE sessiondata SET
access=\'%s\' WHERE id=\'%s\'',
date('YmdHis'),
mysqli_real_escape_string($GLOBALS['sess_mysqli'],
$id))
);
} else {
$ret = '';
}
return $ret;
}
function sess_write($id, $data) {
mysqli_query(
$GLOBALS['sess_mysqli'],

192

sprintf('UPDATE sessiondata SET data=\'%s\',


access=\'%s\' WHERE id=\'%s\'',
mysqli_real_escape_string($GLOBALS['sess_mysqli'],
$data),
date('YmdHis'),

mysqli_real_escape_string($GLOBALS['sess_mysqli'],
$data),
date('YmdHis'),
mysqli_real_escape_string($GLOBALS['sess_mysqli'],
$id))
);
}
return true;
}
function sess_destroy($id) {
mysqli_query(
$GLOBALS['sess_mysqli'],
sprintf('DELETE FROM sessiondata WHERE
id=\'%s\'',

ZAPAMITYWANIE USTAWIE UYTKOWNIKW

mysqli_real_escape_string($GLOBALS['sess_mysqli'],
$id))
);
if
(mysqli_affected_rows($GLOBALS['sess_mysqli']) < 1)
{
mysqli_query(
$GLOBALS['sess_mysqli'],
sprintf('INSERT INTO sessiondata (data,
access, id) VALUES (\'%s\', \'%s\', \'%s\')',

ROZDZIA 5

Implementacja wasnego mechanizmu zarzdzania sesjami

mysqli_real_escape_string($GLOBALS['sess_mysqli'],
$id))
);
return true;
}
function sess_gc($timeout) {
$timestamp = date('YmdHis', time() - $timeout);

193

ROZDZIA 5

Tworzenie zabezpieczonego obszaru z wykorzystaniem sesji

mysqli_query(
$GLOBALS['sess_mysqli'],
sprintf('DELETE FROM sessiondata WHERE access
< \'%s\'',
$timestamp)
);

ZAPAMITYWANIE USTAWIE UYTKOWNIKW

}
session_set_save_handler(
'sess_open', 'sess_close', 'sess_read',
'sess_write', 'sess_destroy', 'sess_gc');
?>

WSKAZWKA
W pliku session.sql w archiwum z przykadami znajduj si
instrukcje SQL suce do utworzenia tabeli bazy danych MySQL. W skrypcie session_mysqli_readwrite.php wykorzystano kod z powyszego listingu w celu zapisania pewnych
danych z wykorzystaniem sesji.
Na rysunku 5.8 pokazano zawarto tabeli session po
zapisaniu do niej danych.

Tworzenie zabezpieczonego
obszaru z wykorzystaniem sesji
session_start();
if (!(isset($_SESSION['authorized']) &&
$_SESSION['authorized'] != '')) {
header("Location:
login.php?url={$_SERVER['PHP_SELF']}");
}

194

Sesje to doskonay sposb zabezpieczenia wydzielonych


czci witryny WWW. Mechanizm jest prosty: po uwierzytelnieniu uytkownika naley zapisa t informacj w zmiennej sesji. Nastpnie na wszystkich zabezpieczonych stronach
wystarczy sprawdzi, czy zdefiniowano t zmienn.
Najpierw sprawdzimy, czy zdefiniowano zmienn sesji.
Kod zamieszczony na pocztku tego podrozdziau naley
wczy (za pomoc instrukcji require_once) na wszystkich stronach, ktre maj by dostpne tylko dla uprawnionych uytkownikw.

ZAPAMITYWANIE USTAWIE UYTKOWNIKW

Rysunek 5.8. Dane sesji s teraz zapisane w bazie danych

ROZDZIA 5

Tworzenie zabezpieczonego obszaru z wykorzystaniem sesji

Skrypt login.php, do ktrego zaprezentowany wczeniej


kod, przekierowuje uytkownika, zawiera formularz HTML
(rysunek 5.9) i sprawdza, czy wprowadzone dane s prawidowe (naley wprowadzi wasnych uytkownikw i ich
195

ROZDZIA 5

ZAPAMITYWANIE USTAWIE UYTKOWNIKW

Tworzenie zabezpieczonego obszaru z wykorzystaniem sesji

Rysunek 5.9. Formularz logowania zwrmy uwag na stron


wymienion w adresie URL

hasa). Jak mona zobaczy, adres URL jest podany jako


parametr GET, a zatem, jeli go zdefiniowano, kod skryptu
logowania przekieruje uytkownika do strony, z ktrej
wysano danie:
<?php
if (isset($_POST['user']) && $_POST['user'] ==
'Damon' &&
isset($_POST['pass']) && $_POST['pass'] ==
'secret') {
session_start();
$_SESSION['authorized'] = 'ok';
$url = (isset($_GET['url'])) ?
nl2br($_GET['url']) : 'index.php';
header("Location: $url");
}
?>

Sprawdzanie danych identyfikacyjnych uytkownika (login.php fragment)

To wszystko! Przykadowy skrypt secret.php zawiera poufne informacje i jest chroniony przez kod zamieszczony
na dwch poprzednich listingach.

196

Tworzenie zabezpieczonego
obszaru bez korzystania z sesji

ROZDZIA 5

Tworzenie zabezpieczonego obszaru bez korzystania z sesji

$_SERVER['PHP_AUTH_USER'] == 'Shelley' &&


$_SERVER['PHP_AUTH_PW'] == 'TopSecret'

<?php
if (!(isset($_SERVER['PHP_AUTH_USER']) &&
isset($_SERVER['PHP_AUTH_PW']) &&
$_SERVER['PHP_AUTH_USER'] == 'Shelley' &&
$_SERVER['PHP_AUTH_PW'] == 'TopSecret')) {
header('WWW-Authenticate: Basic realm="Secured
area"');
header('Status: 401 Unauthorized');
} else {
?>

ZAPAMITYWANIE USTAWIE UYTKOWNIKW

Jeli wykorzystanie uwierzytelniania z mechanizmem zarzdzania sesji PHP wydaje si zbyt duym obcieniem,
mona skorzysta z dwch innych moliwoci. Po pierwsze,
mona skonfigurowa serwer WWW w taki sposb, aby tylko uwierzytelnieni uytkownicy mieli dostp do niektrych
plikw lub katalogw. Na przykad uytkownicy serwera
Apache mog wykorzysta pliki .htaccess. Pod adresem
http://apache-server.com/tutorials/ATusing-htaccess.html
mona znale sporo informacji na ten temat. Serwer
Microsoft IIS jest wyposaony w narzdzie z graficznym
interfejsem uytkownika do definiowania praw dostpu,
a zatem rwnie dla tego serwera mona zdefiniowa
podobny mechanizm.

197

ROZDZIA 5

ZAPAMITYWANIE USTAWIE UYTKOWNIKW


198

Tworzenie zabezpieczonego obszaru bez korzystania z sesji

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0


Transitional//EN" "http://www.w3.org/
TR/xhtml1/DTD/xhtml1-transitional.dtd">
...
<?php
}
?>

Wykorzystanie HTTP do zabezpieczania stron PHP (http_authentication.php


fragment)

Jednym z rozwiza, ktre w duym stopniu jest niezalene


od platformy, jest wykorzystanie uwierzytelniania HTTP.
W przypadku przesania kodu statusu HTTP 401 (nieuprawniony uytkownik) przegldarka wywietli pytanie
o nazw uytkownika i haso. Informacje te s pniej
dostpne w elementach tablicy superglobalnej $_SERVER['PHP_AUTH_USER'] oraz $_SERVER['PHP_AUTH_PW'], ale
jedynie wtedy, gdy PHP dziaa jako modu serwera. Nie
s natomiast dostpne w trybie CGI.
Po sprawdzeniu informacji w tablicy superglobalnej $_
SERVER mona zdecydowa, czy ponownie wysya na-

gwek 401 czy te wywietli zawarto strony. Implementacj tego mechanizmu zaprezentowano na powyszym
listingu. Okno dialogowe z pytaniem o nazw uytkownika i haso pokazano na rysunku 5.10.

Co mona znale w repozytorium pear?


W repozytorium PEAR znajduj si nastpujce pakiety dotyczce sesji i uwierzytelniania HTTP:

pakiet Auth zawiera zbir funkcji sucych do uwierzytelniania uytkownikw, a tym samym do zabezpieczania
stron PHP,

pakiet HTTP_Session bazuje na mechanizmie obsugi


sesji jzyka PHP, ale oferuje obiektowy dostp do informacji dotyczcych sesji.

ZAPAMITYWANIE USTAWIE UYTKOWNIKW

Rysunek 5.10. Przegldarka wywietla pytanie o nazw


uytkownika i haso

ROZDZIA 5

Tworzenie zabezpieczonego obszaru bez korzystania z sesji

199

You might also like