PHP. Rozmówki

49
Wydawnictwo Helion ul. Chopina 6 44-100 Gliwice tel. (32)230-98-63 e-mail: [email protected] PRZYK£ADOWY ROZDZIA£ PRZYK£ADOWY ROZDZIA£ IDZ DO IDZ DO ZAMÓW DRUKOWANY KATALOG ZAMÓW DRUKOWANY KATALOG KATALOG KSI¥¯EK KATALOG KSI¥¯EK TWÓJ KOSZYK TWÓJ KOSZYK CENNIK I INFORMACJE CENNIK I INFORMACJE ZAMÓW INFORMACJE O NOWOŒCIACH ZAMÓW INFORMACJE O NOWOŒCIACH ZAMÓW CENNIK ZAMÓW CENNIK CZYTELNIA CZYTELNIA FRAGMENTY KSI¥¯EK ONLINE FRAGMENTY KSI¥¯EK ONLINE SPIS TREŒCI SPIS TREŒCI DODAJ DO KOSZYKA DODAJ DO KOSZYKA KATALOG ONLINE KATALOG ONLINE PHP. Rozmówki Autor: Christian Wenz T³umaczenie: Rados³aw Meryk ISBN: 83-246-0324-7 Tytu³ orygina³u: PHP Phrasebook Format: B5, stron: 360 Jêzyk PHP to jedna z najpopularniejszych platform programistycznych s³u¿¹cych do tworzenia aplikacji internetowych. Wszêdzie tam, gdzie zamierzamy dynamicznie generowaæ treœæ witryny, gromadziæ i przetwarzaæ dane, identyfikowaæ u¿ytkowników strony lub wysy³aæ pliki do witryny WWW, wykorzystujemy PHP. Gdy pojawiaj¹ siê problemy, wertujemy ksi¹¿ki, szukaj¹c porad i przyk³adów. Jeœli przydatne wskazówki znajduj¹ siê w jednym miejscu, praca szybko posuwa siê do przodu. Ksi¹¿ka „PHP. Rozmówki” to zbiór ponad 100 przyk³adów kodu opatrzonych komentarzami i dok³adnie przetestowanych w ró¿nych systemach operacyjnych i przegl¹darkach. Autor podpowiada gotowe rozwi¹zania problemów, z którymi borykaj¹ siê na co dzieñ programiœci PHP. Przyk³adowy kod z ³atwoœci¹ mo¿na dostosowaæ do w³asnych potrzeb, przyspieszaj¹c w ten sposób pracê nad aplikacj¹ i zwiêkszaj¹c produktywnoœæ. • Operacje na ³añcuchach tekstowych • Stosowanie wyra¿eñ regularnych • Przetwarzanie tablic • Operacje na datach • Obs³uga formularzy WWW • Uwierzytelnianie u¿ytkowników • Stosowanie plików cookie i mechanizmów sesji • Praca z systemem plików na serwerze • Po³¹czenia z bazami danych • Przetwarzanie dokumentów XML • Komunikacja z us³ugami sieciowymi Do efektywnej pracy z PHP wystarczy ta ksi¹¿ka — zatem po co korzystaæ z opas³ych tomów?

description

Język PHP to jedna z najpopularniejszych platform programistycznych służących do tworzenia aplikacji internetowych. Wszędzie tam, gdzie zamierzamy dynamicznie generować treść witryny, gromadzić i przetwarzać dane, identyfikować użytkowników strony lub wysyłać pliki do witryny WWW, wykorzystujemy PHP. Gdy pojawiają się problemy, wertujemy książki, szukając porad i przykładów. Jeśli przydatne wskazówki znajdują się w jednym miejscu, praca szybko posuwa się do przodu. Przyspiesz proces tworzenia aplikacji w PHP-- wykorzystaj gotowe fragmenty kodu. Książka "PHP. Rozmówki" to zbiór ponad 100 przykładów kodu opatrzonych komentarzami i dokładnie przetestowanych w różnych systemach operacyjnych i przeglądarkach. Autor podpowiada gotowe rozwiązania problemów, z którymi borykają się na co dzień programiści PHP. Przykładowy kod z łatwością można dostosować do własnych potrzeb, przyspieszając w ten sposób pracę nad aplikacją i zwiększając produktywność. * Operacje na łańcuchach tekstowych * Stosowanie wyrażeń regularnych * Przetwarzanie tablic * Operacje na datach * Obsługa formularzy WWW * Uwierzytelnianie użytkowników * Stosowanie plików cookie i mechanizmów sesji * Praca z systemem plików na serwerze * Połączenia z bazami danych * Przetwarzanie dokumentów XML * Komunikacja z usługami sieciowymi Do efektywnej pracy z PHP wystarczy ta książka --zatem po co korzystać z opasłych tomów?

Transcript of PHP. Rozmówki

Page 1: PHP. Rozmówki

Wydawnictwo Helionul. Chopina 644-100 Gliwicetel. (32)230-98-63e-mail: [email protected]

PRZYK£ADOWY ROZDZIA£PRZYK£ADOWY ROZDZIA£

IDZ DOIDZ DO

ZAMÓW DRUKOWANY KATALOGZAMÓW DRUKOWANY KATALOG

KATALOG KSI¥¯EKKATALOG KSI¥¯EK

TWÓJ KOSZYKTWÓJ KOSZYK

CENNIK I INFORMACJECENNIK I INFORMACJE

ZAMÓW INFORMACJEO NOWOŒCIACH

ZAMÓW INFORMACJEO NOWOŒCIACH

ZAMÓW CENNIKZAMÓW CENNIK

CZYTELNIACZYTELNIAFRAGMENTY KSI¥¯EK ONLINEFRAGMENTY KSI¥¯EK ONLINE

SPIS TREŒCISPIS TREŒCI

DODAJ DO KOSZYKADODAJ DO KOSZYKA

KATALOG ONLINEKATALOG ONLINE

PHP. RozmówkiAutor: Christian WenzT³umaczenie: Rados³aw MerykISBN: 83-246-0324-7Tytu³ orygina³u: PHP PhrasebookFormat: B5, stron: 360

Jêzyk PHP to jedna z najpopularniejszych platform programistycznych s³u¿¹cych do tworzenia aplikacji internetowych. Wszêdzie tam, gdzie zamierzamy dynamicznie generowaæ treœæ witryny, gromadziæ i przetwarzaæ dane, identyfikowaæ u¿ytkowników strony lub wysy³aæ pliki do witryny WWW, wykorzystujemy PHP. Gdy pojawiaj¹ siê problemy, wertujemy ksi¹¿ki, szukaj¹c porad i przyk³adów. Jeœli przydatne wskazówki znajduj¹ siê w jednym miejscu, praca szybko posuwa siê do przodu.

Ksi¹¿ka „PHP. Rozmówki” to zbiór ponad 100 przyk³adów kodu opatrzonych komentarzami i dok³adnie przetestowanych w ró¿nych systemach operacyjnychi przegl¹darkach. Autor podpowiada gotowe rozwi¹zania problemów, z którymi borykaj¹ siê na co dzieñ programiœci PHP. Przyk³adowy kod z ³atwoœci¹ mo¿na dostosowaædo w³asnych potrzeb, przyspieszaj¹c w ten sposób pracê nad aplikacj¹ i zwiêkszaj¹c produktywnoœæ.

• Operacje na ³añcuchach tekstowych• Stosowanie wyra¿eñ regularnych• Przetwarzanie tablic• Operacje na datach• Obs³uga formularzy WWW• Uwierzytelnianie u¿ytkowników• Stosowanie plików cookie i mechanizmów sesji• Praca z systemem plików na serwerze• Po³¹czenia z bazami danych• Przetwarzanie dokumentów XML• Komunikacja z us³ugami sieciowymi

Do efektywnej pracy z PHP wystarczy ta ksi¹¿ka —zatem po co korzystaæ z opas³ych tomów?

Page 2: PHP. Rozmówki

Spis treści

O autorze ............................................................................11

Wprowadzenie ...................................................................13

1 Operacje na ciągach znaków ..............................................17Porównywanie ciągów znaków ...............................................18Sprawdzanie poprawności nazw użytkowników i haseł ...........19Przekształcanie ciągów znaków na język HTML .......................21Zastosowanie znaków podziału wiersza ..................................24Szyfrowanie ciągów znaków ...................................................25Sprawdzanie sum kontrolnych ciągów znaków .......................27Wydzielanie podciągów znaków ...............................................29Zabezpieczanie adresów e-mail za pomocą kodów ASCII ........30Skanowanie sformatowanych ciągów znaków ........................35Pobieranie szczegółowych informacji o zmiennych ..................36Wyszukiwanie w ciągach znaków ...........................................37Wykorzystanie wyrażeń regularnych POSIX .............................41Wykorzystanie wyrażeń regularnych zgodnych z Perlem ..........43Wyszukiwanie znaczników za pomocą wyrażeń regularnych ......44Sprawdzanie poprawności pól obowiązkowych ......................45

Page 3: PHP. Rozmówki

Spis treści

4

Sprawdzanie poprawności liczb i danych innych typów .......... 47Sprawdzanie poprawności adresów e-mail ............................. 49Wyszukiwanie z zastępowaniem ................................................ 51

2 Tablice ................................................................................55Dostęp do wszystkich elementów tablicy numerycznej .............. 57Dostęp do wszystkich elementów tablicy asocjacyjnej ............ 59Dostęp do wszystkich elementów tablicy zagnieżdżonej ......... 60Przekształcanie elementów tablic na zmienne ........................ 63Konwersja ciągów znaków na tablice ..................................... 64Konwersja tablic na ciągi znaków ........................................... 65Alfabetyczne sortowanie tablic ............................................... 66Alfabetyczne sortowanie tablic asocjacyjnych ......................... 68Sortowanie tablic zagnieżdżonych .......................................... 70Sortowanie zagnieżdżonych tablic asocjacyjnych .................... 72Sortowanie adresów IP (tak jak robiliby to ludzie) .................. 74Sortowanie niestandardowe ................................................... 76Sortowanie z wykorzystaniem znaków narodowych ............... 77Wykonywanie operacji dla wszystkich elementów tablicy ....... 80Filtrowanie tablic ................................................................... 83Losowe pobieranie elementów z tablicy ................................. 84

3 Daty i godziny .....................................................................87Wykorzystanie tekstu wewnątrz funkcji date() ........................ 90Automatyczna lokalizacja dat ................................................. 92Ręczna lokalizacja dat ............................................................ 96Wykorzystanie daty bieżącej w formacie US, UK i europejskim .... 97Formatowanie dowolnych dat ................................................ 98Sprawdzanie poprawności dat ............................................... 99Wykonywanie obliczeń z datami ............................................. 100Tworzenie znaczników czasu, które można sortować ............ 101

Page 4: PHP. Rozmówki

Spis treści

5

Konwersja ciągów znaków na daty .......................................103Określanie czasu wschodu i zachodu słońca ..........................104Wykorzystanie dat i godzin do testów

szybkości działania sprzętu lub programów .......................106Zastosowanie pól formularzy do wyboru dat .........................108Tworzenie samouaktualniających

się pól formularzy do wyboru dat ......................................110Obliczanie różnicy pomiędzy dwiema datami ........................112Wykorzystanie informacji o dacie i godzinie według GMT .....115

4 Interakcje z formularzami WWW ......................................117Przesyłanie danych formularza do bieżącego skryptu ............119Odczyt danych formularzy .....................................................119Magiczne cudzysłowy (apostrofy) ..........................................123Sprawdzenie, czy przesłano formularz ...................................124Zapisywanie danych formularzy w plikach cookie ..................126Wypełnianie pól tekstowych

i pól haseł danymi początkowymi ......................................129Wypełnianie wielowierszowych

pól tekstowych danymi początkowymi ...............................132Domyślne wartości przełączników .........................................134Wypełnianie pól wyboru danymi początkowymi ...................136Wypełnianie list wyboru danymi początkowymi ....................137Wypełnianie list wielokrotnego

wyboru danymi początkowymi ..........................................139Przetwarzanie graficznych przycisków Submit .......................142Sprawdzanie pól obowiązkowych .........................................144Sprawdzanie poprawności list wyboru ..................................146Zapisywanie wszystkich danych formularza w pliku ..............149Wysyłanie wszystkich danych formularza pocztą elektroniczną ..151

Page 5: PHP. Rozmówki

Spis treści

6

Pobieranie informacji na temat plikówwgrywanych na serwer ..................................................... 153

Przenoszenie plików wgranychna serwer do bezpiecznej lokalizacji .................................. 156

5 Zapamiętywanie ustawień użytkowników— pliki cookie i sesje .....................................................159

Istota plików cookie ............................................................. 160Tworzenie plików cookie ...................................................... 163Odczytywanie plików cookie ................................................ 164Pozbywanie się „magicznych” cudzysłowów (apostrofów)

z plików cookie ................................................................. 166Ustawianie daty ważności względem innej daty ................... 167Ustawianie daty ważności specyficznej dla klienta ................ 169Usuwanie plików cookie ...................................................... 170Udostępnianie plików cookie dla wielu domen ..................... 172Sprawdzanie, czy klient obsługuje pliki cookie ...................... 174Zapisywanie wielu danych w jednym pliku cookie ................ 176Zapisywanie ustawień językowych użytkownika ................... 178Sesje .................................................................................... 181Gdzie należy zapisywać sesje? .............................................. 182W jaki sposób zachować stan sesji? ..................................... 183Aktywacja sesji .................................................................... 184Czytanie i zapisywanie sesji ................................................. 185Zamykanie sesji .................................................................... 186Modyfikacje identyfikatora sesji ............................................ 187Tworzenie dynamicznych łączy z obsługą sesji ...................... 188Implementacja własnego mechanizmu zarządzania sesjami .. 190Tworzenie zabezpieczonego obszaru z wykorzystaniem sesji 194Tworzenie zabezpieczonego obszaru bez korzystania z sesji . 197

Page 6: PHP. Rozmówki

Spis treści

7

6 Wykorzystanie plików zapisanychw systemie plików serwera ...........................................201

Otwieranie i zamykanie plików .............................................202Odczytywanie danych z plików .............................................206Zapisywanie danych do pliku ................................................208Blokowanie plików ...............................................................210Wykorzystanie ścieżek względnych

w celu uzyskania dostępu do pliku ....................................212Unikanie niebezpiecznych pułapek związanych

z dostępem do plików .......................................................213Wykorzystanie danych w formacie CSV .................................215Przetwarzanie plików INI ......................................................220Odczytywanie informacji o plikach ........................................222Kopiowanie, przenoszenie i usuwanie plików .......................225Przeglądanie systemu plików ................................................226Wykorzystanie strumieni w PHP ...............................................227Wykorzystanie archiwów Bzip2 .............................................229Zwracanie plików za pomocą żądania HTTP ..........................232

7 Tworzenie danych dynamicznych .....................................235Nawiązywanie połączenia z bazą danych ..............................237Nawiązywanie połączenia z bazą danych

z wykorzystaniem rozszerzenia MySQLi ................................238Wysyłanie instrukcji SQL do bazy danych MySQL ...................240Instrukcje preparowane w MySQL-u ......................................242Odczytywanie wyników zapytania do bazy danych MySQL ....245Nawiązywanie połączenia z bazą danych SQLite ...................248Wysyłanie instrukcji SQL do bazy danych SQLite ....................250Odczytywanie wyników zapytania do bazy danych SQLite .....251Nawiązywanie połączenia z bazą danych PostgreSQL ............253Wysyłanie zapytań SQL do bazy danych PosgreSQL ...............255

Page 7: PHP. Rozmówki

Spis treści

8

Aktualizacja danych w PostgreSQL ....................................... 256Odczytywanie wyników zapytania

do bazy danych PostgreSQL .............................................. 257Nawiązywanie połączenia z bazą danych Oracle .................. 259Wysyłanie instrukcji SQL do bazy danych Oracle ................... 260Odczytywanie wyników zapytania do bazy danych Oracle .... 263Nawiązywanie połączenia z bazą danych MSSQL ................. 265Przesyłanie instrukcji SQL do bazy danych MSSQL ................. 267Odczytywanie wyników zapytania do bazy danych MSSQL ... 269Nawiązywanie połączenia z bazą danych Firebird ................. 270Przesyłanie instrukcji SQL do bazy danych Firebird ................ 272Odczytywanie wyników zapytania do bazy danych Firebird .. 273Nawiązywanie połączenia z bazami danych za pomocą PDO ....... 274Przesyłanie instrukcji SQL za pomocą PDO ............................ 277Odczytywanie wyników zapytań przesyłanych za pomocą PDO ..278

8 Wykorzystanie XML-a .......................................................281Przetwarzanie XML za pomocą interfejsu SAX ...................... 282Odczyt dokumentów XML

z wykorzystaniem modelu DOM w PHP 4 .......................... 285Odczyt dokumentów XML

z wykorzystaniem modelu DOM w PHP 5 .......................... 287Wykorzystanie modelu DOM

do zapisywania dokumentów XML w PHP 4 ...................... 289Wykorzystanie modelu DOM

do zapisywania dokumentów XML w PHP 5 ...................... 291Wykorzystanie rozszerzenia SimpleXML ................................ 292Transformacje dokumentów XML

z wykorzystaniem XSL w PHP 4 ......................................... 294Transformacje dokumentów XMLz wykorzystaniem XSL w PHP 5 ............................................. 295

Sprawdzanie poprawności dokumentów XML ...................... 296

Page 8: PHP. Rozmówki

Spis treści

9

9 Komunikacja ze światem zewnętrznym ...........................299Nawiązywanie połączenia z serwerami HTTP ........................299Łączenie się z serwerami FTP ................................................303Sprawdzanie, czy serwer odpowiada ....................................305Tworzenie usług sieciowych

z wykorzystaniem pakietu PEAR::XML-RPC ........................310Korzystanie z usługi sieciowej

za pomocą pakietu PEAR::XML-RPC ................................312Tworzenie usługi sieciowej za pomocą klasy NuSOAP ...........314Automatyczne generowanie kodu WSDL

z wykorzystaniem klasy NuSOAP ........................................315Wykorzystanie usługi sieciowej zaimplementowanej

za pomocą klasy NuSOAP ..................................................319Tworzenie usług sieciowych

za pomocą pakietu PEAR::SOAP .........................................320Automatyczne generowanie kodu WSDL dla usług sieciowychzaimplementowanych za pomocą pakietu PEAR::SOAP .........322Wykorzystanie usługi sieciowej zaimplementowanej

za pomocą pakietu PEAR::SOAP .........................................324Tworzenie usług sieciowych

z wykorzystaniem rozszerzenia SOAP w PHP 5 ...................325Wykorzystanie usług sieciowych tworzonych

za pomocą rozszerzenia SOAP w PHP 5 ..............................328

Skorowidz .........................................................................335

Page 9: PHP. Rozmówki

5Zapamiętywanie ustawień użytkowników

Zapamiętywanieustawień użytkowników

— pliki cookie i sesje

TTP (Hypertext Transfer Protocol) jest protokołem bez-stanowym. Mówiąc prosto, klient (przeglądarka WWW)łączy się z serwerem WWW, przesyła żądanie i uzyskujeodpowiedź. Następnie połączenie jest zamykane. W konse-kwencji, jeśli następnym razem ten sam klient prześle żądaniedo tego samego serwera WWW, będzie to nowe żądanie,a zatem serwer WWW nie będzie mógł zidentyfikowaćużytkownika. Takie działanie stanowi oczywisty problemdla aplikacji, które muszą utrzymywać stany (na przykładaplikacji e-commerce z implementacją koszyka na zakupy).

Z ograniczeniem tym można jednak sobie poradzić na kilkasposobów. Podstawowa idea polega na przesłaniu pew-nych informacji wraz z odpowiedzią HTTP. Informacjete są przesyłane do serwera we wszystkich kolejnych żą-daniach. Istnieją następujące możliwości:

H

Page 10: PHP. Rozmówki

Istota plików cookie

160

ZAPA

MIĘ

TYW

ANIE

UST

AWIEŃ

UŻY

TKO

WN

IKÓ

WR

OZ

DZ

IAŁ

5

wysłanie danych za pomocą metody POST (tzn. zakażdym razem wymagany jest formularz),

wysłanie danych za pomocą metody GET (tzn. po-przez dołączenie informacji do adresu URI żądania),

wysłanie danych jako części nagłówka HTTP (w po-staci pliku cookie).

W praktyce używa się jednej z dwóch metod: sesji (z wy-korzystaniem metody GET lub plików cookie) oraz pli-ków cookie.

Istota plików cookiePliki cookie są przesyłane w nagłówkach HTTP. W uprosz-czeniu, plik cookie składa się z pary nazwa-wartość. Najważ-niejszą wadą plików cookie jest możliwość ich blokowaniaw przeglądarkach WWW (a także filtrowania na serwe-rach proxy). Niektórzy uważają, że pliki cookie stanowiązagrożenie dla prywatności użytkowników. Po części przy-czyną tego poglądu był artykuł Johna Udella z marca 1997roku, w którym autor stwierdził, że każdy plik cookiemożna odczytać z każdego serwera WWW, a zatem włą-czenie obsługi plików cookie oznacza utratę prywatności.Artykuł spowodował zamieszanie. Niestety, sprostowa-nie opublikowane dwa miesiące później nie wzbudziłojuż takiego zainteresowania.

Prawdą jest, że pliki cookie mają pewne ograniczenia:

Page 11: PHP. Rozmówki

Istota plików cookie

161

ZAPAMIĘTYW

ANIE USTAW

IEŃ UŻYTKO

WN

IKÓW

RO

ZD

ZIAŁ

5

są powiązane z domenami — zazwyczaj z domeną,z której wysłano plik cookie,

mogą być powiązane z katalogami na serwerze WWW,

zawierają wyłącznie informacje tekstowe; maksymalnie4096 bajtów (włącznie z nazwą pliku cookie i zna-kami = pomiędzy nazwami a wartościami),

przeglądarki mogą zaakceptować tylko do 20 plikówcookie na domenę i 300 plików cookie w ogóle (choćniektóre przeglądarki akceptują więcej).

UWAGA

Nieoficjalna specyfikacja plików cookie jest związana z prze-glądarką Netscape i ciągle jest dostępna pod adresem http://

wp.netscape.com/newsref/std/cookie_spec.html. Były próbystworzenia specjalnego dokumentu RFC dotyczącego plikówcookie nowej generacji, ale inicjatywy te nie doczekały sięjeszcze obsługi w żadnej z popularnych przeglądarek.

Pliki cookie są przesyłane w nagłówkach HTTP. W przy-padku ustawienia pliku cookie w nagłówku HTTP tworzysię zapis Set-Cookie. Dalej występuje nazwa i wartośćpliku cookie (obie w postaci ciągu znaków) oraz opcjo-nalnie inne informacje, takie jak data ważności, domenai ścieżka dostępu do pliku cookie. Na przykład, jeśli od-wiedzimy witrynę http://www.php.net, witryna PHP prześlenagłówek w następującej postaci (oczywiście ustawieniajęzyka i adres IP mogą być inne):

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

Page 12: PHP. Rozmówki

Istota plików cookie

162

ZAPA

MIĘ

TYW

ANIE

UST

AWIEŃ

UŻY

TKO

WN

IKÓ

WR

OZ

DZ

IAŁ

5

Kiedy przeglądarka (lub użytkownik) zaakceptuje plik co-okie, zostanie on przesłany na serwer podany w nagłówkuHTTP Cookie:

Cookie:COUNTRY=DEU%2C84.154.17.84

Dla pliku cookie można ustawić datę ważności. Jeśli zo-stanie ustawiona, plik będzie przechowywany co najwyżejdo tej daty. Jest to tzw. trwały plik cookie (ang. persistentcookie). Po upływie tego okresu przeglądarka automa-tycznie go usunie — choć może to również zdarzyć sięwcześniej; na przykład w przypadku zapisania maksy-malnej liczby plików cookie w przeglądarce najstarsze plikicookie zostaną usunięte. Jeśli data ważności pliku cookienie zostanie ustawiona, taki plik określa się jako tzw.plik sesji lub plik tymczasowy. Pliki cookie tego typu sąprzechowywane tak długo, jak długo działa przeglądarkaWWW. Podczas zamykania przeglądarki tymczasowe plikicookie są usuwane.

WSKAZÓWKA

Aby oglądać nagłówki HTTP, można skorzystać ze specjalnychrozszerzeń standardowych przeglądarek WWW. W przypadkuprzeglądarek Mozilla (włącznie z przeglądarką Firefox) wielkiemożliwości oferuje rozszerzenie LiveHTTPHeaders dostępnepod adresem http://livehttpheaders.mozdev.org/. Użytkownicyprzeglądarki Microsoft Internet Explorer mogą zainstalowaćpasek narzędzi ieHTTPHeaders dostępny pod adresem http://

www.blunck.info/iehttpheaders.html. Na rysunku 5.1 po-kazano przykładowe nagłówki dla przeglądarki FireFox pod-czas dostępu do strony macierzystej PHP.

Page 13: PHP. Rozmówki

Tworzenie plików cookie

163

ZAPAMIĘTYW

ANIE USTAW

IEŃ UŻYTKO

WN

IKÓW

RO

ZD

ZIAŁ

5

Rysunek 5.1. Pliki cookie są ustawiane w nagłówkach HTTP

Tworzenie plików cookie<?php setcookie('version', phpversion());?>Próba wysłania pliku cookie.

Do tworzenia plików cookie służy funkcja PHP set-cookie(). Funkcja przyjmuje następujące parametry (tylko

pierwszy z nich jest obowiązkowy):

1. Nazwa pliku cookie.

2. Wartość pliku cookie.

3. Data ważności (w formacie uniksowego znacznika czasu).

4. Katalog na serwerze WWW, z którego można uzyskaćdostęp do pliku cookie.

5. Domena, z której można uzyskać dostęp do pliku cookie.

Page 14: PHP. Rozmówki

Odczytywanie plików cookie

164

ZAPA

MIĘ

TYW

ANIE

UST

AWIEŃ

UŻY

TKO

WN

IKÓ

WR

OZ

DZ

IAŁ

5

6. Informacja, czy plik cookie można przesyłać tylko zapomocą bezpiecznych połączeń HTTPS (SSL).

W kodzie zamieszczonym na początku tego podrozdziałuustawiono prosty plik cookie sesji z wartością w postacibieżącej wersji PHP.

Na rysunku 5.2 pokazano okno z ostrzeżeniem wyświe-tlane w przeglądarce Firefox. Bez trudu można odczytaćnazwę pliku cookie i jego wartość.

Rysunek 5.2. Firefox otrzymuje plik cookie i wyświetla pytaniedo użytkownika o to, co z nim zrobić

Odczytywanie plików cookieWszystkie pliki cookie, do których serwer ma dostęp (niemuszą to być wszystkie pliki cookie, które są zapisanew przeglądarce!) są dostępne w tablicy superglobalnej

Page 15: PHP. Rozmówki

Odczytywanie plików cookie

165

ZAPAMIĘTYW

ANIE USTAW

IEŃ UŻYTKO

WN

IKÓW

RO

ZD

ZIAŁ

5

$_COOKIE. W kodzie zaprezentowanym poniżej wszystkiepliki cookie są odczytywane w pętli foreach i wysyłanedo klienta w postaci tabeli HTML.

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

Czytanie plików cookie (getcookie.php)

OSTRZEŻENIE

Ponieważ pliki cookie są przesyłane jako nagłówki HTTP,muszą być utworzone przed wysłaniem wyjścia HTML (chybaże korzystamy z buforowania wyników). W innym przypadkuuzyskamy komunikat o błędzie podobny do tego, który poka-zano na rysunku 5.3.

Rysunek 5.3. Pliki cookie trzeba przesłać przed wysłaniemzawartości HTML

Page 16: PHP. Rozmówki

Pozbywanie się „magicznych” cudzysłowów z plików cookie

166

ZAPA

MIĘ

TYW

ANIE

UST

AWIEŃ

UŻY

TKO

WN

IKÓ

WR

OZ

DZ

IAŁ

5

UWAGA

Zazwyczaj interpreter PHP automatycznie unieszkodliwia znakispecjalne w wartościach plików cookie poprzez poprzedzenieich znakami lewego ukośnika (szczególnie w przypadku przeka-zywania plików cookie poprzez URL). Jednak począwszy odPHP 5 można to robić ręcznie, poprzez wysłanie „surowych”danych pliku cookie. Aby to uczynić, należy przekazać dofunkcji setrawcookie() te same parametry, które byłyprzekazane do funkcji setcookie(). Obie funkcje działająpodobnie. Różnica polega na tym, że pierwsza z nich nie ko-duje wartości pliku cookie. Aby ją zakodować, należy ręczniewywołać funkcję urlencode().

Pozbywanie się „magicznych” cudzysłowów z plików cookie

Pozbywanie się „magicznych”cudzysłowów (apostrofów)z plików cookieMagiczne cudzysłowy (apostrofy), które opisano i wyklętow poprzednim rozdziale, dotyczą również plików cookie,ponieważ to również są dane pochodzące od klientów. Takwięc, jeśli ustawiono opcję magic_quotes na wartość on,znaki apostrofów i cudzysłowów będą poprzedzane zna-kiem lewego ukośnika. Aby pozbyć się ukośników, moż-na wykorzystać poniższy kod. Podobny kod zastosowanow poprzednim rozdziale do usunięcia ukośników z danychformularzy (danych GET i POST).

Page 17: PHP. Rozmówki

Ustawianie daty ważności względem innej daty

167

ZAPAMIĘTYW

ANIE USTAW

IEŃ UŻYTKO

WN

IKÓW

RO

ZD

ZIAŁ

5

Jeśli ustawiono opcję magic_quotes, funkcja stripsla-shes() będzie wywoływana rekurencyjnie dla wszystkich

danych w tablicy $_COOKIE.

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

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

Usuwanie „magicznych” cudzysłowów (apostrofów) z plików cookie(stripCookieSlashes.inc.php)

Skrypt stripCookieSlashes.inc.php należy włączyć do wszyst-kich skryptów PHP, które odczytują pliki cookie za po-mocą następującej instrukcji:

require_once 'stripCookieSlashes.inc.php';

Ustawianie daty ważnościwzględem innej datyData ważności pliku cookie jest przekazywana za pomocątrzeciego parametru funkcji setcookie(). Jest to liczbacałkowita, dlatego trzeba użyć uniksowego znacznika czasu.

Page 18: PHP. Rozmówki

Ustawianie daty ważności względem innej daty

168

ZAPA

MIĘ

TYW

ANIE

UST

AWIEŃ

UŻY

TKO

WN

IKÓ

WR

OZ

DZ

IAŁ

5

W rozdziale 3., „Daty i godziny”, zamieszczono sporoinformacji dotyczących sposobu wykorzystania tego ro-dzaju danych.

<?php setcookie('version', phpversion(), time() + 21*24*60*60);?>Próba wysłania pliku cookie.

Ustawianie daty ważności pliku cookie względem innej daty(setcookie-expiry.php)

Zwykle lepszym pomysłem jest ustawienie daty ważnościpliku cookie względem innej daty („za trzy tygodnie”), niżpodawanie daty konkretnej („koniec maja 2006”). W przy-padku użycia dat bezwzględnych skrypt trzeba regularniemodyfikować, ponieważ często data wygaśnięcia ważnościnadchodzi bardzo szybko. Ustawianie czasu ważności nabardzo odległa datę w przyszłości, na przykład w roku2030, uważa się za działanie nieprofesjonalne. Klient, któryotrzyma taki plik cookie, najprawdopodobniej w roku2030 już nie będzie się logował na serwerze.

Z tych względów warto stosować daty względem innychdat. Funkcja PHP date() pobiera wartość uniksowegoznacznika czasu dla daty bieżącej. Do tej wartości wy-starczy dodać liczbę sekund, przez jaką plik cookie mabyć ważny. Kod zaprezentowany na poprzednim listinguustawia plik cookie, który będzie ważny przez trzy ty-godnie.

Page 19: PHP. Rozmówki

Ustawianie daty ważności specyficznej dla klienta

169

ZAPAMIĘTYW

ANIE USTAW

IEŃ UŻYTKO

WN

IKÓW

RO

ZD

ZIAŁ

5

Ustawianie daty ważnościspecyficznej dla klientasetcookie('version', phpversion(), $_GET['time'] + 21*24*60*60)

Należy pamiętać, że decyzja dotyczące tego, kiedy plikcookie traci ważność, jest podejmowana po stronie klientai z wykorzystaniem ustawień daty i godziny klienta. Jeślizatem data klienta jest ustawiona nieprawidłowo (czegopo stronie serwera nie można kontrolować), pliki cookiebędą traciły ważność wcześniej lub później niż się spodzie-wamy. Nie warto zatem ustawiać plików cookie, którebędą ważne przez godzinę. Nasze plany mogą zniweczyćtak błahe sytuacje jak zmiana czasu z zimowego na letni.

<?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); }?>Próba wysłania pliku cookie.

Ustawianie pliku cookie z określoną datą ważności (setcookie-specific.php)

Wystarczy jednak odrobina kodu w JavaScript, aby uniknąćopisanej pułapki. Kod zamieszczony na poniższym listinguto działający po stronie klienta skrypt JavaScript, którysprawdza bieżącą godzinę wyrażoną jako uniksowy znacznik

Page 20: PHP. Rozmówki

Usuwanie plików cookie

170

ZAPA

MIĘ

TYW

ANIE

UST

AWIEŃ

UŻY

TKO

WN

IKÓ

WR

OZ

DZ

IAŁ

5

czasu i wysyła ją do działającego na serwerze skryptu set-cookie-specific.php. Najważniejsza różnica pomiędzy funk-cją PHP time() a metodą getTime() języka JavaScriptpolega na tym, że ta druga zwraca liczbę milisekund, jakieupłynęły od północy 1 stycznia 1970 roku, natomiast pierw-sza liczbę sekund. Z tego powodu wartość otrzymaną zeskryptu JavaScript należy najpierw podzielić przez 1000i zaokrąglić w dół do całości.

Kod skryptu setcookie-specific.php zamieszczono na po-czątku tego podrozdziału. Przesyłana wartość jest wykorzy-stywana jako podstawa obliczenia relatywnej daty ważnościpliku 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 plików cookiesetcookie('version', '', time() - 10*365*24*60*60);

Intuicyjnym sposobem usunięcia pliku cookie jest usta-wienie jego wartości na pusty ciąg znaków. Ta operacjanie powoduje jednak usunięcia pliku cookie. Plik w dal-szym ciągu istnieje, choć już nie ma ustawionej wartości.Lepszym sposobem jest ponowne przesłanie tego samego

Page 21: PHP. Rozmówki

Usuwanie plików cookie

171

ZAPAMIĘTYW

ANIE USTAW

IEŃ UŻYTKO

WN

IKÓW

RO

ZD

ZIAŁ

5

pliku cookie z datą ważności w przeszłości. Także w tymprzypadku trzeba uwzględnić nieprawidłowe ustawieniaczasu lokalnego, a zatem należy wybierać bardzo odległedaty utraty ważności, na przykład 10 lat wcześniej. Sposóbten zaimplementowano poniżej, gdzie usunięto plik cookieustawiony w kodzie pokazanym na poprzednim listingu.W tej implementacji połączono obie metody — ustawionowartość na pusty ciąg znaków i datę wygaśnięcia plikucookie w przeszłości. Wynik działania skryptu pokazanona rysunku 5.4 — przeglądarka próbuje usunąć plik cookiepoprzez ustawienie daty jego wygaśnięcia na określonyczas (w przeszłości, a zatem plik cookie przestaje istnieć).

Rysunek 5.4. Plik cookie będzie usunięty (jeśli użytkownik gozaakceptuje)

<?php setcookie('version', '', time() -10*365*24*60*60);?>Próba usunięcia pliku cookie.

Usuwanie plików cookie (deletecookie.php)

Page 22: PHP. Rozmówki

Udostępnianie plików cookie dla wielu domen

172

ZAPA

MIĘ

TYW

ANIE

UST

AWIEŃ

UŻY

TKO

WN

IKÓ

WR

OZ

DZ

IAŁ

5

OSTRZEŻENIE

Jeśli spróbujemy ustawić datę utraty ważności na 0, PHP pomi-nie ten parametr, a zatem ten sposób nie zadziała. Trzebaużyć argumentu o dodatniej wartości — na przykład 1.

Udostępnianie plików cookiedla wielu domensetcookie('version', phpversion(), 0,'.przyklad.com');

Częścią nagłówka Set-Cookie wysyłanego przez serwerjest domena, która ma dostęp do tego pliku cookie. Jeśliwartość ta nie zostanie określona jawnie, domyślnie przyj-muje się domenę, z której wysłano plik cookie. Próbaustawienia tej wartości na całkiem inną domenę — na przy-kład serwera reklam (tzw. pliki cookie firm zewnętrznych,używane w celu wygenerowania profilu użytkownika) —nie zawsze zadziała, ponieważ wiele przeglądarek umoż-liwia zablokowanie takiej możliwości (na rysunku 5.5widać, że taką możliwość miały już stare przeglądarkiNetscape 4.x).

<?php setcookie('version', phpversion(), 0,'.przyklad.com');?>Próba przesłania pliku cookie.

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

Page 23: PHP. Rozmówki

Udostępnianie plików cookie dla wielu domen

173

ZAPAMIĘTYW

ANIE USTAW

IEŃ UŻYTKO

WN

IKÓW

RO

ZD

ZIAŁ

5

Rysunek 5.5. Nawet w przeglądarce Netscape 4.x możnazablokować pliki cookie, które pochodzą z innych domen

W niektórych przypadkach istnieje potrzeba, aby pliki co-okie działały w kilku domenach zewnętrznych lub poddo-menach, na przykład www.przyklad.com, sklep.przyklad.comi ssl.przyklad.com. Sytuacja dotyczy dużych witryn WWWz wieloma poddomenami, takich jak Amazon czy eBay.Witryny te wymagają obsługi dla wszystkich domen naj-wyższego poziomu. Aby to było możliwe, trzeba ustawićdomenę pliku cookie — czwarty parametr funkcji set-cookie(). Jest jednak pewien kłopot: nazwy domen są

prawidłowe, o ile zawierają dwie kropki. Jeśli zatem usta-wimy domenę na .przyklad.com, do pliku cookie będą

Page 24: PHP. Rozmówki

Sprawdzanie, czy klient obsługuje pliki cookie

174

ZAPA

MIĘ

TYW

ANIE

UST

AWIEŃ

UŻY

TKO

WN

IKÓ

WR

OZ

DZ

IAŁ

5

miały dostęp wszystkie domeny trzeciego poziomu domenyprzyklad.com. Jest jednak jedno „ale”. Strony umieszczonew domenie http://przyklad.com nie będą miały dostępu dotego pliku cookie. Można zatem spróbować ustawić dome-nę na przyklad.com, ale to nie jest zgodne ze specyfikacjąi może nie zadziałać w niektórych przeglądarkach.

Sprawdzanie, czy klientobsługuje pliki cookie $test_temp = isset($_COOKIE['test_temp']) ? 'obsługuje' : 'nie obsługuje'; $test_persist = isset($_COOKIE['test_persist']) ? 'obsługuje' : 'nie obsługuje';

Pamiętacie, w jaki sposób są przesyłane pliki cookie? Naj-pierw serwer przesyła plik cookie do klienta w odpowiedziHTTP. W następnym żądaniu, jeśli użytkownik zaak-ceptuje plik cookie, klient przesyła go z powrotem naserwer. Z tego powodu wywołanie funkcji setcookie()i późniejsze sprawdzenie zawartości tablicy $_COOKIE niezadziała. Trzeba zaczekać na kolejne żądanie HTTP.

<?php if (isset($_GET['step']) && $_GET['step'] == '2') { $test_temp = isset($_COOKIE['test_temp']) ? 'obsługuje' : 'nie obsługuje'; $test_persist = isset($_COOKIE['test_persist']) ? 'obsługuje' : 'nie obsługuje'; setcookie('test_temp', '', time() - 365*24*60*60); setcookie('test_persist', '', time() - 365*24*60*60);

Page 25: PHP. Rozmówki

Sprawdzanie, czy klient obsługuje pliki cookie

175

ZAPAMIĘTYW

ANIE USTAW

IEŃ UŻYTKO

WN

IKÓW

RO

ZD

ZIAŁ

5

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

Testowanie konfiguracji plików cookie przeglądarki (cookietest.php)

Można jednak skorzystać z funkcji header() i wymusićutworzenie drugiego żądania klienta. W pierwszym żąda-niu ustawiamy plik cookie, w drugim sprawdzamy, czyoperacja zakończyła się sukcesem.

W zaprezentowanym powyżej kodzie ustawiono dwa plikicookie — jeden tymczasowy i drugi trwały — ponieważniektóre przeglądarki można tak skonfigurować, że jedentyp plików cookie będzie akceptowany, a drugi nie. Na-stępnie, aby sprawdzić ustawienie wszystkich plików co-okie, wystarczy wykonać przekierowanie za pomocą funkcjiheader() oraz nagłówka HTTP Location.

Oczywiście trzeba tak skonfigurować przeglądarkę, abyw momencie przesłania pliku cookie był wyświetlany ko-munikat — znacznie ułatwia to debugowanie.

Page 26: PHP. Rozmówki

Zapisywanie wielu danych w jednym pliku cookie

176

ZAPA

MIĘ

TYW

ANIE

UST

AWIEŃ

UŻY

TKO

WN

IKÓ

WR

OZ

DZ

IAŁ

5

Zapisywanie wielu danychw jednym pliku cookiesetcookie('cookiedata', serialize($cookiedata)

Zazwyczaj w pliku cookie jest ustawiona jedna wartość— ciąg znaków. Z tego powodu, aby zapisać za pomocąplików cookie wiele danych, trzeba użyć wielu plikówcookie. Takie działanie stwarza jednak pewne problemy— na przykład z powodu ograniczenia 20 plików cookiena domenę. Z tego względu w niektórych przypadkachma sens zapisywanie wielu danych w jednym pliku cookie.Do tego przydają się tablice.

Wartościami plików cookie mogą być jednak wyłącznieciągi znaków. Z tego powodu tablicę trzeba przekształcićna ciąg znaków za pomocą funkcji serialize(). Późniejmożna ją przekształcić 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),

Page 27: PHP. Rozmówki

Zapisywanie wielu danych w jednym pliku cookie

177

ZAPAMIĘTYW

ANIE USTAW

IEŃ UŻYTKO

WN

IKÓW

RO

ZD

ZIAŁ

5

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

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

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 można napisać bibliotekę podobną do tej,którą wykorzystywaliśmy w poprzednim rozdziale do zapi-sywania danych formularza w pliku cookie. Jeden plikcookie o nazwie cookiedata zawiera wszystkie wartości za-pisane w postaci tablicy asocjacyjnej. Funkcja getCookie-Data() zwraca jedną wartość, natomiast setCookieDate()

pobiera tablicę i zapisuje jej zawartość do pliku cookie.Kompletny kod źródłowy tej biblioteki pokazano na po-wyższym listingu.

Page 28: PHP. Rozmówki

Zapisywanie ustawień językowych użytkownika

178

ZAPA

MIĘ

TYW

ANIE

UST

AWIEŃ

UŻY

TKO

WN

IKÓ

WR

OZ

DZ

IAŁ

5

Z kolei na listingu zamieszczonym poniżej wykorzystanozdefiniowaną bibliotekę do zaimplementowania testu dlaplików cookie znanych z poprzedniego podrozdziału.

<?php require_once 'getCookieData.inc.php';

if (isset($_GET['step']) && $_GET['step'] == '2') { $test = (getCookieData('test') == 'ok') ? 'obsługuje' : 'nie obsługuje'; echo "Przeglądarka $test pliki cookie."; } else { setCookieData(array('test' => 'ok')); header("Location: {$_SERVER['PHP_SELF']}?step=2"); }?>

Zapisywanie ustawieńjęzykowych użytkownikasetcookie('lang', $_SERVER['PHP_SELF'], time() +30*24*60*60, '/')

Bardzo często strony WWW obsługują wiele języków.Zazwyczaj są one tak zorganizowane, że każda zlokalizo-wana część witryny jest zapisana w osobnym katalogu, naprzykład w następującej konfiguracji:

wersja dla języka angielskiego jest zapisana w kata-logu en,

wersja dla języka hiszpańskiego jest zapisana w ka-talogu es,

Page 29: PHP. Rozmówki

Zapisywanie ustawień językowych użytkownika

179

ZAPAMIĘTYW

ANIE USTAW

IEŃ UŻYTKO

WN

IKÓW

RO

ZD

ZIAŁ

5

wersja dla języka francuskiego jest zapisana w kata-logu fr,

wersja dla języka polskiego jest zapisana w katalogu pl.

Język użytkownika można wykryć na kilka sposobów:

próbując powiązać adres IP klienta z określonym re-gionem geograficznym,

odczytując nagłówek HTTP Accept-Language, z któ-rego można się dowiedzieć, jakie języki są preferowane,

zadając użytkownikowi pytanie.

Chociaż każda z tych metod jest w jakimś stopniu skutecz-na, ostatnia (lub kombinacja kilku) jest uważana za najbar-dziej przyjazną dla użytkownika. Trzeba zatem zdefiniowaćstronę macierzystą zawierającą łącza do wszystkich dostęp-nych wersji językowych. Wystarczy prosty język HTML:

<a href="en/index.php">English version</a><br /> <a href="es/index.php">Versión espańol</a><br /> <a href="fr/index.php">Versione française</a><br /> <a href="pl/index.php">Wersja polska</a>

Strona macierzysta zawiera łącza do różnych wersji językowych (multilingual.php— fragment)

W katalogu dla każdego języka znajduje się skrypt index.phpnapisany w określonej wersji językowej. W tym pliku prze-chowywany jest kod z listingu zamieszczonego na początkutego podrozdziału. Instrukcja sprawdza, czy już ustawionoplik cookie dla wersji językowej, a jeśli nie — ustawia plikcookie dla bieżącego katalogu (odczytanego za pomocąodwołania do elementu $_SERVER['PHP_SELF']).

Page 30: PHP. Rozmówki

Zapisywanie ustawień językowych użytkownika

180

ZAPA

MIĘ

TYW

ANIE

UST

AWIEŃ

UŻY

TKO

WN

IKÓ

WR

OZ

DZ

IAŁ

5

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

Zapisywanie informacji o bieżącym katalogu w pliku cookie(savelanguage.inc.php)

UWAGA

Jest bardzo istotne, aby ustawić ścieżkę pliku cookie nagłówny katalog serwera WWW. W innym przypadku warto-ścią domyślną ścieżki będzie katalog bieżący i plik będziemógł być odczytany tylko w katalogu bieżącym i jego pod-katalogach. Nie będzie go można go odczytać ze strony ma-cierzystej.

Na koniec, na stronie macierzystej trzeba sprawdzić, czyustawiono plik cookie, a jeśli tak, przekierować użytkow-nika na stronę zawierającą odpowiednią wersję językową.W tym celu na początku skryptu multilingual.php trzebawprowadzić następujący kod:

<?php if (isset($_COOKIE['lang']) && $_COOKIE['lang'] != '') { header("Location: {$_COOKIE['lang']}"); }?>

Page 31: PHP. Rozmówki

Sesje

181

ZAPAMIĘTYW

ANIE USTAW

IEŃ UŻYTKO

WN

IKÓW

RO

ZD

ZIAŁ

5

SesjeSesja to nic innego jak wizyta użytkownika na stronieWWW. Użytkownik klika jakieś łącza, przegląda niektórestrony i wychodzi. Działania użytkownika w witrynieWWW definiują sesję. Jeśli użytkownik nie zażąda danychz witryny WWW przez pewien czas, na przykład 20 mi-nut, sesja kończy się.

Protokół HTTP nie zawiera żadnego mechanizmu obsługisesji, ponieważ jest bezstanowy. PHP zawiera jednak wbu-dowaną obsługę sesji, dzięki czemu skorzystanie z nich jeststosunkowo proste.

Po utworzeniu sesji PHP generuje jej identyfikator w posta-ci długiego ciągu znaków. Następnie tworzy zapis w plikulub bazie danych dotyczący określonej sesji. Po wykonaniutych operacji aplikacja PHP może zapisywać dane w sesji.Dane te trafiają do pliku sesji bądź do bazy danych (rza-dziej dane sesji są zapisywane w pamięci współdzielonej).

Zatem jedynym elementem, który musi być przekazywanypomiędzy klientem a serwerem jest identyfikator sesji.Wszystkie pozostałe dane związane z sesją są przechowy-wane na serwerze. Dzięki temu w łączu nie są niepotrzebnieprzesyłane istotne dane.

Konfiguracja mechanizmu sesji języka PHP jest w całościzapisana w sekcji [session] pliku konfiguracyjnego php.ini.Domyślne ustawienia nie pasują do wszystkich zastoso-wań, dlatego w kolejnych podrozdziałach opisano kilkamożliwych konfiguracji.

Page 32: PHP. Rozmówki

Gdzie należy zapisywać sesje?

182

ZAPA

MIĘ

TYW

ANIE

UST

AWIEŃ

UŻY

TKO

WN

IKÓ

WR

OZ

DZ

IAŁ

5

Gdzie należy zapisywać sesje?Zazwyczaj dane sesji są zapisywane w plikach. Lokalizacjętych plików ustawia się za pomocą dyrektywy pliku php.inisession.save_path. Oczywiście katalog ustawiony za po-mocą tej dyrektywy musi po pierwsze istnieć, a po drugieproces PHP (zwykle proces serwera WWW) musi miećw nim uprawnienia odczytu i zapisu. W innym przypad-ku danych sesji nie można zapisać.

Jednak w przypadku dużej liczby użytkowników, a co zatym idzie dużej liczby sesji, interpreter PHP nie powinienumieszczać wszystkich plików sesji w jednym katalogu, po-nieważ może to wpłynąć na znaczne obniżenie wydajno-ści. Poniższa instrukcja umożliwia przenoszenie danychsesji do wielu podkatalogów:

session.save_path = "n;/tmp"

Skorzystanie z tej dyrektywy spowoduje utworzenie pod-katalogów w katalogu /tmp do 5 poziomów w głąb. Abymechanizm sesji PHP mógł zapisywać dane w podkata-logach, trzeba je wcześniej utworzyć. Do tego celu służyskrypt mod_files.sh w katalogu ext/sessions.

Oczywiście prawo do odczytywania tego katalogu powi-nien posiadać tylko serwer WWW. W innym przypadkuinni użytkownicy systemu mogliby odczytywać informa-cje o sesji potencjalnie zawierające wrażliwe dane.

Page 33: PHP. Rozmówki

W jaki sposób zachować stan sesji?

183

ZAPAMIĘTYW

ANIE USTAW

IEŃ UŻYTKO

WN

IKÓW

RO

ZD

ZIAŁ

5

W jaki sposóbzachować stan sesji?Identyfikator sesji musi być przesłany do przeglądarkiw każdej odpowiedzi, a co ważniejsze — musi być prze-słany z powrotem na serwer wraz z każdym żądaniem.

Najprościej można zaimplementować ten mechanizm zapomocą plików cookie. PHP przesyła do klienta plik cookieo nazwie PHPSESSID (nazwę można zmienić za pomocą dy-rektywy pliku php.ini session.name). Aby było to moż-liwe, należy ustawić następującą dyrektywę pliku php.ini:

session.use_cookies = 1

Co jednak zrobić, jeśli użytkownik wyłączy obsługę pli-ków cookie? W takim przypadku można skorzystać z in-nego mechanizmu. W tym celu należy ustawić następującądyrektywę:

session.use_trans_sid = 0

W tym przypadku PHP automatycznie ustawia tryb, w któ-rym identyfikator sesji jest dołączany do wszystkich ad-resów URL. Takie rozwiązanie może powodować pewnezagrożenie (na przykład modyfikowanie sesji — ang. sessionfixation, lub przechwytywanie sesji — ang. session hijac-king), ale jest dość praktyczne. Wykorzystują je wszyst-kie znane witryny e-commerce, na przykład Amazon. Jeśliodwiedzimy ich witrynę WWW i załadujemy stronę, iden-tyfikator sesji zostanie automatycznie dołączony na końcuadresu URL.

Page 34: PHP. Rozmówki

Aktywacja sesji

184

ZAPA

MIĘ

TYW

ANIE

UST

AWIEŃ

UŻY

TKO

WN

IKÓ

WR

OZ

DZ

IAŁ

5

Aby można było skorzystać z ustawienia session.user_trans_sid, PHP musi być skompilowane z przełączni-

kiem -enable-trans-sid. Opcja ta jest automatyczniewłączona dla binarnych dystrybucji przeznaczonych dlasystemów Windows i Mac OS X.

Można również zezwolić na przekazywanie w adresachURL tylko plików cookie, bez identyfikatorów sesji. Dotego służy następująca dyrektywa pliku php.ini:

session.use_only_cookies = 1

UWAGA

Przekazywanie identyfikatorów sesji w adresach URL w za-sadzie jest złe, ponieważ odwiedzający mogą zapisywać jew postaci zakładek, niektóre wyszukiwarki nie uwzględniająwitryn, w których stosuje się tę technikę itd. W każdej witry-nie e-commerce (a także w większości innych witryn) trzebajednak wziąć pod uwagę, że niektórzy odwiedzający (poten-cjalni klienci!) nie włączą obsługi plików cookie. W takimprzypadku sesje gwarantują wygodny sposób pokonania tegoograniczenia.

Aktywacja sesjisession_start()

Korzystanie z mechanizmów zarządzania sesjami zawszewymaga zasobów, a w związku z tym wiąże się z obniże-niem wydajności. Dlatego właśnie sesje trzeba aktywować.

Page 35: PHP. Rozmówki

Czytanie i zapisywanie sesji

185

ZAPAMIĘTYW

ANIE USTAW

IEŃ UŻYTKO

WN

IKÓW

RO

ZD

ZIAŁ

5

Ponieważ operacja ta może wymagać przesłania plikówcookie, trzeba to zrobić przed wysłaniem do klienta za-wartości HTML. Można to zrobić na dwa sposoby:

globalna aktywacja sesji za pomocą dyrektywy plikuphp.ini session.auto_start = 1,

aktywacja sesji na poziomie skryptu, za pomocą funkcjisession_start().

Z punktu widzenia wydajności 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 zostały odczytane:{$_SESSION['version']} .";?>

Dostęp do wszystkich danych sesji w skrypcie PHP moż-na uzyskać za pomocą tablicy $_SESSION. Ponieważ danesą zapisane po stronie serwera, można zapisać dane sesjii odczytać je już w następnej instrukcji PHP bez konieczno-ści transmisji, tak jak to było w przypadku plików cookie.

Page 36: PHP. Rozmówki

Zamykanie sesji

186

ZAPA

MIĘ

TYW

ANIE

UST

AWIEŃ

UŻY

TKO

WN

IKÓ

WR

OZ

DZ

IAŁ

5

Wystarczy pamiętać o wywołaniu funkcji session_start().Potem można korzystać z tablicy $_SESSION. Kod za-mieszczony na listingu na początku tego podrozdziału two-rzy plik sesji pokazany na rysunku 5.6.

Rysunek 5.6. Zawartość pliku sesji utworzonego przez kodpokazany na poprzednim listingu

Zamykanie sesjisession_destroy()

W niektórych przypadkach, na przykład kiedy użytkowniksię wyloguje, wszystkie dane sesji należy usunąć, a sesję za-mknąć. Oczywiście można przetworzyć tablicę $_SESSIONw pętli foreach i ustawić każdą z wartości na pusty ciągznaków, ale istnieje szybszy sposób — wystarczy wywołaćfunkcję session_destroy(). Po wykonaniu tej funkcji,tak jak wskazuje nazwa (destroy — niszczyć), wszystkiedane w bieżącej sesji zostaną zniszczone.

<?php session_start(); echo 'Przed: <pre>'; print_r($_SESSION); echo '</pre>Po: <pre> '; session_destroy();

Page 37: PHP. Rozmówki

Modyfikacje identyfikatora sesji

187

ZAPAMIĘTYW

ANIE USTAW

IEŃ UŻYTKO

WN

IKÓW

RO

ZD

ZIAŁ

5

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

Usuwanie wszystkich danych sesji (session_destroy.php)

Modyfikacjeidentyfikatora sesjisession_regenerate_id()

Jednym ze znanych ataków przeciwko witrynom WWWzabezpieczonych za pomocą sesji jest przechwycenie iden-tyfikatora sesji użytkownika (na przykład w wyniku analizyzapisów HTTP_REFERER w żądaniach HTTP), a następniewykorzystanie go w celu podszycia się pod niego. Z ta-kimi atakami trudno się walczy, można jednak utrudnićżycie napastnikom, zmieniając identyfikator sesji każdo-razowo, kiedy coś ważnego się zmienia, na przykład gdyużytkownik się zaloguje. Przykładowo w witrynie Amazonużytkownicy, którzy zostali wcześniej uwierzytelnieni zapomocą pliku cookie, gdy chcą coś zamówić, muszą się po-nownie zalogować.

<?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)

Page 38: PHP. Rozmówki

Tworzenie dynamicznych łączy z obsługą sesji

188

ZAPA

MIĘ

TYW

ANIE

UST

AWIEŃ

UŻY

TKO

WN

IKÓ

WR

OZ

DZ

IAŁ

5

W tym przypadku funkcja session_regenerate_id()modyfikuje bieżący identyfikator sesji, ale pozostawia zapi-sane w niej dane bez zmian. Pokazano to w zamieszczonymwcześniej kodzie, gdzie za pomocą funkcji session_id()odczytano stary i bieżący identyfikator sesji. Przykładowywynik działania tego skryptu pokazano na rysunku 5.7.

Rysunek 5.7. Dwa identyfikatory sesji: stary i nowy

UWAGA

W tym kodzie wykorzystano buforowanie wyników — funk-cje ob_start() i ob_end_flush() — ponieważ funkcjęsession_regenerate_id() trzeba wywołać przed wysła-niem do klienta wyniku HTML.

Tworzenie dynamicznych łączyz obsługą sesji$name = urlencode(session_name());$id = urlencode(session_id());echo "<a href=\"page.php?$name=$id\">dynamicznełącze</a>";

Page 39: PHP. Rozmówki

Tworzenie dynamicznych łączy z obsługą sesji

189

ZAPAMIĘTYW

ANIE USTAW

IEŃ UŻYTKO

WN

IKÓW

RO

ZD

ZIAŁ

5

Zastosowanie ustawienia session.use_trans_sid w celuautomatycznej aktualizacji wszystkich łączy w taki sposób,by zawierały identyfikatory sesji, to dobry pomysł, jednaksposób ten nie zadziała, jeśli łącza będą generowane auto-matycznie przez PHP. W PHP istnieją jednak dwie funkcje,które dostarczają wszystkich potrzebnych informacji:

session_name() — zwraca nazwę sesji,

session_id() — zwraca bieżący identyfikator sesji.

Tak więc kod zamieszczony na początku tego podrozdziałutworzy dynamiczne łącze zawierające informacje o sesji.W ten sposób programista może tworzyć dynamiczne łączaz obsługą sesji.

Oto przykładowy wynik działania zamieszczonego wyżejkodu:

<a href="page.php?PHPSESSID=2600b43e0fecb4d5a990bf848289a8fe">dynamiczne łącze</a>

WSKAZÓWKA

Kiedy korzystamy z formularzy HTML, PHP automatyczniedołącza identyfikator sesji do atrybutu action formularza.Jednak, aby wykorzystać formularze dynamiczne, można do-dać ukryte pole zawierające informacje o sesji:

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

Page 40: PHP. Rozmówki

Implementacja własnego mechanizmu zarządzania sesjami

190

ZAPA

MIĘ

TYW

ANIE

UST

AWIEŃ

UŻY

TKO

WN

IKÓ

WR

OZ

DZ

IAŁ

5

Implementacja własnegomechanizmu zarządzaniasesjamisession_set_save_handler( 'sess_open', 'sess_close', 'sess_read','sess_write', 'sess_destroy', 'sess_gc');

Istnieją powody, dla których nie powinno się zapisywaćdanych sesji w plikach. Wydajność to jedno, a bezpieczeń-stwo to drugie. Alternatywnie można zapisywać dane sesjiw bazach danych. Aby można to było zrobić, należy utwo-rzyć tabelę bazy danych sessiondata z trzema kolumnami(ich nazwy mogą być różne, jednak należy je konsekwentniestosować w kodzie zaprezentowanym na listingach za-mieszczonych poniżej):

kolumna id (klucz główny) 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 znacz-nik czasu ostatniego dostępu do danych sesji.

Nie ma znaczenia, jaką bazę danych wykorzystamy. W tympodrozdziale wykorzystano bazę MySQL i nowe rozsze-rzenie PHP5 — mysqli. Bez trudu można jednak tak zmo-dyfikować kod, aby działał również z innymi bazami danych(więcej informacji dotyczących wykorzystania różnych bazdanych w PHP można znaleźć w rozdziale 7.).

Page 41: PHP. Rozmówki

Implementacja własnego mechanizmu zarządzania sesjami

191

ZAPAMIĘTYW

ANIE USTAW

IEŃ UŻYTKO

WN

IKÓW

RO

ZD

ZIAŁ

5

Funkcję PHP session_set_save_handler() można wy-korzystać do zdefiniowania własnych funkcji dla sześciuoperacji wewnętrznie wykonywanych przez PHP:

otwierania sesji,

zamykania sesji,

odczytywania zmiennej sesji,

zapisywania zmiennej sesji,

niszczenia sesji,

porządkowania (tzw. odśmiecania — ang. garbagecollection — polegającego, na przykład, na usuwaniustarych danych sesji z bazy danych).

Kod dla wszystkich tych sześciu operacji, który odczytujei zapisuje dane sesji do i z bazy danych MySQL, za-mieszczono na poniższym listingu. Aby z niego skorzy-stać, trzeba zainstalować PHP 5 i odpowiednio ustawićparametry połączenia (serwer, nazwę użytkownika, hasło).Następnie należy włączyć kod zamieszczony na poniższymlistingu za pomocą funkcji require_once. Po wykonaniutych operacji można wykorzystywać sesje w standardowysposób. Od tego momentu PHP będzie zapisywał informa-cje dotyczące sesji w bazie danych, a nie w plikach.

<?php $GLOBALS['sess_server'] = 'localhost'; $GLOBALS['sess_db'] = 'sessions'; $GLOBALS['sess_username'] = 'user'; $GLOBALS['sess_password'] = 'pass';

function sess_open() {

Page 42: PHP. Rozmówki

Implementacja własnego mechanizmu zarządzania sesjami

192

ZAPA

MIĘ

TYW

ANIE

UST

AWIEŃ

UŻY

TKO

WN

IKÓ

WR

OZ

DZ

IAŁ

5

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

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'],

Page 43: PHP. Rozmówki

Implementacja własnego mechanizmu zarządzania sesjami

193

ZAPAMIĘTYW

ANIE USTAW

IEŃ UŻYTKO

WN

IKÓW

RO

ZD

ZIAŁ

5

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'],$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\')',

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\'',

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

Page 44: PHP. Rozmówki

Tworzenie zabezpieczonego obszaru z wykorzystaniem sesji

194

ZAPA

MIĘ

TYW

ANIE

UST

AWIEŃ

UŻY

TKO

WN

IKÓ

WR

OZ

DZ

IAŁ

5

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

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

WSKAZÓWKA

W pliku session.sql w archiwum z przykładami znajdują sięinstrukcje SQL służące do utworzenia tabeli bazy danych My-SQL. W skrypcie session_mysqli_readwrite.php wykorzysta-no kod z powyższego listingu w celu zapisania pewnychdanych z wykorzystaniem sesji.

Na rysunku 5.8 pokazano zawartość tabeli session pozapisaniu do niej danych.

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

Page 45: PHP. Rozmówki

Tworzenie zabezpieczonego obszaru z wykorzystaniem sesji

195

ZAPAMIĘTYW

ANIE USTAW

IEŃ UŻYTKO

WN

IKÓW

RO

ZD

ZIAŁ

5

Rysunek 5.8. Dane sesji są teraz zapisane w bazie danych

Sesje to doskonały sposób zabezpieczenia wydzielonychczęści witryny WWW. Mechanizm jest prosty: po uwierzy-telnieniu użytkownika należy zapisać tę informację w zmien-nej sesji. Następnie na wszystkich zabezpieczonych stronachwystarczy sprawdzić, czy zdefiniowano tę zmienną.

Najpierw sprawdzimy, czy zdefiniowano zmienną sesji.Kod zamieszczony na początku tego podrozdziału należywłączyć (za pomocą instrukcji require_once) na wszyst-kich stronach, które mają być dostępne tylko dla upraw-nionych użytkowników.

Skrypt login.php, do którego zaprezentowany wcześniejkod, przekierowuje użytkownika, zawiera formularz HTML(rysunek 5.9) i sprawdza, czy wprowadzone dane są prawi-dłowe (należy wprowadzić własnych użytkowników i ich

Page 46: PHP. Rozmówki

Tworzenie zabezpieczonego obszaru z wykorzystaniem sesji

196

ZAPA

MIĘ

TYW

ANIE

UST

AWIEŃ

UŻY

TKO

WN

IKÓ

WR

OZ

DZ

IAŁ

5

Rysunek 5.9. Formularz logowania — zwróćmy uwagę na stronęwymienioną w adresie URL

hasła). Jak można zobaczyć, adres URL jest podany jakoparametr GET, a zatem, jeśli go zdefiniowano, kod skryptulogowania przekieruje użytkownika do strony, z którejwysłano żą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 użytkownika (login.php — fragment)

To wszystko! Przykładowy skrypt secret.php zawiera po-ufne informacje i jest chroniony przez kod zamieszczonyna dwóch poprzednich listingach.

Page 47: PHP. Rozmówki

Tworzenie zabezpieczonego obszaru bez korzystania z sesji

197

ZAPAMIĘTYW

ANIE USTAW

IEŃ UŻYTKO

WN

IKÓW

RO

ZD

ZIAŁ

5

Tworzenie zabezpieczonegoobszaru bez korzystania z sesji$_SERVER['PHP_AUTH_USER'] == 'Shelley' &&$_SERVER['PHP_AUTH_PW'] == 'TopSecret'

Jeśli wykorzystanie uwierzytelniania z mechanizmem za-rządzania sesji PHP wydaje się zbyt dużym obciążeniem,można skorzystać z dwóch innych możliwości. Po pierwsze,można skonfigurować serwer WWW w taki sposób, aby tyl-ko uwierzytelnieni użytkownicy mieli dostęp do niektórychplików lub katalogów. Na przykład użytkownicy serweraApache mogą wykorzystać pliki .htaccess. Pod adresemhttp://apache-server.com/tutorials/ATusing-htaccess.htmlmożna znaleźć sporo informacji na ten temat. SerwerMicrosoft IIS jest wyposażony w narzędzie z graficznyminterfejsem użytkownika do definiowania praw dostępu,a zatem również dla tego serwera można zdefiniowaćpodobny mechanizm.

<?phpif (!(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 {?>

Page 48: PHP. Rozmówki

Tworzenie zabezpieczonego obszaru bez korzystania z sesji

198

ZAPA

MIĘ

TYW

ANIE

UST

AWIEŃ

UŻY

TKO

WN

IKÓ

WR

OZ

DZ

IAŁ

5

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">...<?php}?>

Wykorzystanie HTTP do zabezpieczania stron PHP (http_authentication.php— fragment)

Jednym z rozwiązań, które w dużym stopniu jest niezależneod platformy, jest wykorzystanie uwierzytelniania HTTP.W przypadku przesłania kodu statusu HTTP 401 (nie-uprawniony użytkownik) przeglądarka wyświetli pytanieo nazwę użytkownika i hasło. Informacje te są późniejdostępne w elementach tablicy superglobalnej $_SERVER-['PHP_AUTH_USER'] oraz $_SERVER['PHP_AUTH_PW'], ale

jedynie wtedy, gdy PHP działa jako moduł serwera. Niesą natomiast dostępne w trybie CGI.

Po sprawdzeniu informacji w tablicy superglobalnej $_SERVER można zdecydować, czy ponownie wysyłać na-

główek 401 czy też wyświetlić zawartość strony. Imple-mentację tego mechanizmu zaprezentowano na powyższymlistingu. Okno dialogowe z pytaniem o nazwę użytkow-nika i hasło pokazano na rysunku 5.10.

Page 49: PHP. Rozmówki

Tworzenie zabezpieczonego obszaru bez korzystania z sesji

199

ZAPAMIĘTYW

ANIE USTAW

IEŃ UŻYTKO

WN

IKÓW

RO

ZD

ZIAŁ

5

Rysunek 5.10. Przeglądarka wyświetla pytanie o nazwęużytkownika i hasło

Co można znaleźć w repozytorium pear?

W repozytorium PEAR znajdują się następujące pakiety doty-czące sesji i uwierzytelniania HTTP:

pakiet Auth zawiera zbiór funkcji służących do uwierzy-telniania użytkowników, a tym samym do zabezpieczaniastron PHP,

pakiet HTTP_Session bazuje na mechanizmie obsługisesji języka PHP, ale oferuje obiektowy dostęp do infor-macji dotyczących sesji.