SlideShare ist ein Scribd-Unternehmen logo
1 von 49
Downloaden Sie, um offline zu lesen
IDZ DO
         PRZYK£ADOWY ROZDZIA£

                           SPIS TREŒCI
                                         PHP. Rozmówki
                                         Autor: Christian Wenz
           KATALOG KSI¥¯EK               T³umaczenie: Rados³aw Meryk
                                         ISBN: 83-246-0324-7
                      KATALOG ONLINE     Tytu³ orygina³u: PHP Phrasebook
                                         Format: B5, stron: 360
       ZAMÓW DRUKOWANY KATALOG


              TWÓJ KOSZYK
                    DODAJ DO KOSZYKA     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
         CENNIK I INFORMACJE             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
                   ZAMÓW INFORMACJE      znajduj¹ siê w jednym miejscu, praca szybko posuwa siê do przodu.
                     O NOWOŒCIACH        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
                       ZAMÓW CENNIK      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
                 CZYTELNIA               produktywnoϾ.
                                             • Operacje na ³añcuchach tekstowych
          FRAGMENTY KSI¥¯EK ONLINE           • 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 —
Wydawnictwo Helion                                              zatem po co korzystaæ z opas³ych tomów?
ul. Chopina 6
44-100 Gliwice
tel. (32)230-98-63
e-mail: helion@helion.pl
Spis treści

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

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

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


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

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

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

4
Spis treści


   Konwersja ciągów znaków na daty .......................................103
   Określanie czasu wschodu i zachodu słońca ..........................104
   Wykorzystanie dat i godzin do testów
     szybkości działania sprzętu lub programów .......................106
   Zastosowanie pól formularzy do wyboru dat .........................108
   Tworzenie samouaktualniających
     się pól formularzy do wyboru dat ......................................110
   Obliczanie różnicy pomiędzy dwiema datami ........................112
   Wykorzystanie informacji o dacie i godzinie według GMT .....115

4 Interakcje z formularzami WWW ......................................117
  Przesyłanie danych formularza do bieżącego skryptu ............119
  Odczyt danych formularzy .....................................................119
  Magiczne cudzysłowy (apostrofy) ..........................................123
  Sprawdzenie, czy przesłano formularz ...................................124
  Zapisywanie danych formularzy w plikach cookie ..................126
  Wypełnianie pól tekstowych
    i pól haseł danymi początkowymi ......................................129
  Wypełnianie wielowierszowych
    pól tekstowych danymi początkowymi ...............................132
  Domyślne wartości przełączników .........................................134
  Wypełnianie pól wyboru danymi początkowymi ...................136
  Wypełnianie list wyboru danymi początkowymi ....................137
  Wypełnianie list wielokrotnego
    wyboru danymi początkowymi ..........................................139
  Przetwarzanie graficznych przycisków Submit .......................142
  Sprawdzanie pól obowiązkowych .........................................144
  Sprawdzanie poprawności list wyboru ..................................146
  Zapisywanie wszystkich danych formularza w pliku ..............149
  Wysyłanie wszystkich danych formularza pocztą elektroniczną ..151


                                                                                      5
Spis treści


        Pobieranie informacji na temat plików
          wgrywanych na serwer ..................................................... 153
        Przenoszenie plików wgranych
          na serwer do bezpiecznej lokalizacji .................................. 156

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


6
Spis treści


6 Wykorzystanie plików zapisanych
    w systemie plików serwera ...........................................201
  Otwieranie i zamykanie plików .............................................202
  Odczytywanie danych z plików .............................................206
  Zapisywanie danych do pliku ................................................208
  Blokowanie plików ...............................................................210
  Wykorzystanie ścieżek względnych
    w celu uzyskania dostępu do pliku ....................................212
  Unikanie niebezpiecznych pułapek związanych
    z dostępem do plików .......................................................213
  Wykorzystanie danych w formacie CSV .................................215
  Przetwarzanie plików INI ......................................................220
  Odczytywanie informacji o plikach ........................................222
  Kopiowanie, przenoszenie i usuwanie plików .......................225
  Przeglądanie systemu plików ................................................226
  Wykorzystanie strumieni w PHP ...............................................227
  Wykorzystanie archiwów Bzip2 .............................................229
  Zwracanie plików za pomocą żądania HTTP ..........................232

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


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

    8 Wykorzystanie XML-a .......................................................281
      Przetwarzanie XML za pomocą interfejsu SAX ...................... 282
      Odczyt dokumentów XML
        z wykorzystaniem modelu DOM w PHP 4 .......................... 285
      Odczyt dokumentów XML
        z wykorzystaniem modelu DOM w PHP 5 .......................... 287
      Wykorzystanie modelu DOM
        do zapisywania dokumentów XML w PHP 4 ...................... 289
      Wykorzystanie modelu DOM
        do zapisywania dokumentów XML w PHP 5 ...................... 291
      Wykorzystanie rozszerzenia SimpleXML ................................ 292
      Transformacje dokumentów XML
        z wykorzystaniem XSL w PHP 4 ......................................... 294
      Transformacje dokumentów XML
       z wykorzystaniem XSL w PHP 5 ............................................. 295
      Sprawdzanie poprawności dokumentów XML ...................... 296
8
Spis treści


9 Komunikacja ze światem zewnętrznym ...........................299
  Nawiązywanie połączenia z serwerami HTTP ........................299
  Łączenie się z serwerami FTP ................................................303
  Sprawdzanie, czy serwer odpowiada ....................................305
  Tworzenie usług sieciowych
    z wykorzystaniem pakietu PEAR::XML-RPC ........................310
  Korzystanie z usługi sieciowej
    za pomocą pakietu PEAR::XML-RPC ................................312
  Tworzenie usługi sieciowej za pomocą klasy NuSOAP ...........314
  Automatyczne generowanie kodu WSDL
    z wykorzystaniem klasy NuSOAP ........................................315
  Wykorzystanie usługi sieciowej zaimplementowanej
    za pomocą klasy NuSOAP ..................................................319
  Tworzenie usług sieciowych
    za pomocą pakietu PEAR::SOAP .........................................320
  Automatyczne generowanie kodu WSDL dla usług sieciowych
  zaimplementowanych za pomocą pakietu PEAR::SOAP .........322
  Wykorzystanie usługi sieciowej zaimplementowanej
    za pomocą pakietu PEAR::SOAP .........................................324
  Tworzenie usług sieciowych
    z wykorzystaniem rozszerzenia SOAP w PHP 5 ...................325
  Wykorzystanie usług sieciowych tworzonych
    za pomocą rozszerzenia SOAP w PHP 5 ..............................328

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




                                                                                            9
5
      Zapamiętywanie
                                                          Zapamiętywanieua ieuyo nó
                                                                         swńżt wikw
                                                                         t k




ustawień użytkowników
  — pliki cookie i sesje

HTTP (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 uzyskuje
odpowiedź. Następnie połączenie jest zamykane. W konse-
kwencji, jeśli następnym razem ten sam klient prześle żądanie
do 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 problem
dla aplikacji, które muszą utrzymywać stany (na przykład
aplikacji e-commerce z implementacją koszyka na zakupy).

Z ograniczeniem tym można jednak sobie poradzić na kilka
sposobów. Podstawowa idea polega na przesłaniu pew-
nych informacji wraz z odpowiedzią HTTP. Informacje
te są przesyłane do serwera we wszystkich kolejnych żą-
daniach. Istnieją następujące możliwości:
Istota plików cookie
ROZDZIAŁ 5


                                            wysłanie danych za pomocą metody POST (tzn. za
                                            każ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).
ZAPAMIĘTYWANIE USTAWIEŃ UŻYTKOWNIKÓW




                                       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 cookie
                                       Pliki 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 blokowania
                                       w 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 1997
                                       roku, w którym autor stwierdził, że każdy plik cookie
                                       moż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ło
                                       już takiego zainteresowania.

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


                     160
Istota plików cookie




                                                                     ROZDZIAŁ 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; maksymalnie
    4096 bajtów (włącznie z nazwą pliku cookie i zna-
    kami = pomiędzy nazwami a wartościami),




                                                                     ZAPAMIĘTYWANIE USTAWIEŃ UŻYTKOWNIKÓW
    przeglądarki mogą zaakceptować tylko do 20 plików
    cookie 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óby
 stworzenia specjalnego dokumentu RFC dotyczącego plików
 cookie 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 tworzy
się 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, domena
i ścieżka dostępu do pliku cookie. Na przykład, jeśli od-
wiedzimy witrynę http://www.php.net, witryna PHP prześle
nagłówek w następującej postaci (oczywiście ustawienia
języka i adres IP mogą być inne):

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

                                                                    161
Istota plików cookie
ROZDZIAŁ 5


                                       Kiedy przeglądarka (lub użytkownik) zaakceptuje plik co-
                                       okie, zostanie on przesłany na serwer podany w nagłówku
                                       HTTP 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żej
ZAPAMIĘTYWANIE USTAWIEŃ UŻYTKOWNIKÓW




                                       do tej daty. Jest to tzw. trwały plik cookie (ang. persistent
                                       cookie). 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 pliki
                                       cookie zostaną usunięte. Jeśli data ważności pliku cookie
                                       nie 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ądarka
                                       WWW. Podczas zamykania przeglądarki tymczasowe pliki
                                       cookie są usuwane.

                                        WSKAZÓWKA
                                        Aby oglądać nagłówki HTTP, można skorzystać ze specjalnych
                                        rozszerzeń standardowych przeglądarek WWW. W przypadku
                                        przeglądarek Mozilla (włącznie z przeglądarką Firefox) wielkie
                                        możliwości oferuje rozszerzenie LiveHTTPHeaders dostępne
                                        pod adresem http://livehttpheaders.mozdev.org/. Użytkownicy
                                        przeglą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.

                     162
Tworzenie plików cookie




                                                                    ROZDZIAŁ 5
                                                                    ZAPAMIĘTYWANIE USTAWIEŃ UŻYTKOWNIKÓW
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.
                                                                   163
Odczytywanie plików cookie
ROZDZIAŁ 5


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

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

                                       Na rysunku 5.2 pokazano okno z ostrzeżeniem wyświe-
ZAPAMIĘTYWANIE USTAWIEŃ UŻYTKOWNIKÓW




                                       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 pytanie
                                       do użytkownika o to, co z nim zrobić



                                       Odczytywanie plików cookie
                                       Wszystkie pliki cookie, do których serwer ma dostęp (nie
                                       muszą to być wszystkie pliki cookie, które są zapisane
                                       w przeglądarce!) są dostępne w tablicy superglobalnej
                     164
Odczytywanie plików cookie




                                                                       ROZDZIAŁ 5
$_COOKIE. W kodzie zaprezentowanym poniżej wszystkie
pliki cookie są odczytywane w pętli foreach i wysyłane
do klienta w postaci tabeli HTML.

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




                                                                       ZAPAMIĘTYWANIE USTAWIEŃ UŻYTKOWNIKÓW
       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 przypadku
 uzyskamy 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łaniem
zawartości HTML
                                                                      165
Pozbywanie się „magicznych” cudzysłowów z plików cookie
ROZDZIAŁ 5


                                                   UWAGA
                                                   Zazwyczaj interpreter PHP automatycznie unieszkodliwia znaki
                                                   specjalne w wartościach plików cookie poprzez poprzedzenie
                                                   ich znakami lewego ukośnika (szczególnie w przypadku przeka-
                                                   zywania plików cookie poprzez URL). Jednak począwszy od
                                                   PHP 5 można to robić ręcznie, poprzez wysłanie „surowych”
                                                   danych pliku cookie. Aby to uczynić, należy przekazać do
ZAPAMIĘTYWANIE USTAWIEŃ UŻYTKOWNIKÓW




                                                   funkcji setrawcookie() te same parametry, które były
                                                   przekazane 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ęcznie
                                                   wywołać funkcję urlencode().



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




                                       cudzysłowów (apostrofów)
                                       z plików cookie
                                       Magiczne cudzysłowy (apostrofy), które opisano i wyklęto
                                       w poprzednim rozdziale, dotyczą również plików cookie,
                                       ponieważ to również są dane pochodzące od klientów. Tak
                                       wię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 zastosowano
                                       w poprzednim rozdziale do usunięcia ukośników z danych
                                       formularzy (danych GET i POST).




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




                                                                         ROZDZIAŁ 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 {




                                                                         ZAPAMIĘTYWANIE USTAWIEŃ UŻYTKOWNIKÓW
       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ści
względem innej daty
Data ważności pliku cookie jest przekazywana za pomocą
trzeciego parametru funkcji setcookie(). Jest to liczba
całkowita, dlatego trzeba użyć uniksowego znacznika czasu.


                                                                        167
Ustawianie daty ważności względem innej daty
ROZDZIAŁ 5


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

                                        <?php
                                          setcookie('version', phpversion(), time() +
                                          21*24*60*60);
                                        ?>
                                        Próba wysłania pliku cookie.
ZAPAMIĘTYWANIE USTAWIEŃ UŻYTKOWNIKÓW




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

                                       Zwykle lepszym pomysłem jest ustawienie daty ważności
                                       pliku 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 regularnie
                                       modyfikować, ponieważ często data wygaśnięcia ważności
                                       nadchodzi bardzo szybko. Ustawianie czasu ważności na
                                       bardzo odległa datę w przyszłości, na przykład w roku
                                       2030, uważa się za działanie nieprofesjonalne. Klient, który
                                       otrzyma taki plik cookie, najprawdopodobniej w roku
                                       2030 już nie będzie się logował na serwerze.

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




                     168
Ustawianie daty ważności specyficznej dla klienta




                                                                              ROZDZIAŁ 5
Ustawianie daty ważności
specyficznej dla klienta
 setcookie('version', phpversion(),
     $_GET['time'] + 21*24*60*60)


Należy pamiętać, że decyzja dotyczące tego, kiedy plik




                                                                              ZAPAMIĘTYWANIE USTAWIEŃ UŻYTKOWNIKÓW
cookie traci ważność, jest podejmowana po stronie klienta
i z wykorzystaniem ustawień daty i godziny klienta. Jeśli
zatem data klienta jest ustawiona nieprawidłowo (czego
po stronie serwera nie można kontrolować), pliki cookie
będą traciły ważność wcześniej lub później niż się spodzie-
wamy. Nie warto zatem ustawiać plików cookie, które
bę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 listingu
to działający po stronie klienta skrypt JavaScript, który
sprawdza bieżącą godzinę wyrażoną jako uniksowy znacznik

                                                                             169
Usuwanie plików cookie
ROZDZIAŁ 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 JavaScript
                                       polega na tym, że ta druga zwraca liczbę milisekund, jakie
                                       upłynęły od północy 1 stycznia 1970 roku, natomiast pierw-
                                       sza liczbę sekund. Z tego powodu wartość otrzymaną ze
                                       skryptu JavaScript należy najpierw podzielić przez 1000
ZAPAMIĘTYWANIE USTAWIEŃ UŻYTKOWNIKÓW




                                       i 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ści
                                       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 plików cookie
                                        setcookie('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 operacja
                                       nie 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


                     170
Usuwanie plików cookie




                                                                      ROZDZIAŁ 5
pliku cookie z datą ważności w przeszłości. Także w tym
przypadku trzeba uwzględnić nieprawidłowe ustawienia
czasu lokalnego, a zatem należy wybierać bardzo odległe
daty utraty ważności, na przykład 10 lat wcześniej. Sposób
ten zaimplementowano poniżej, gdzie usunięto plik cookie
ustawiony w kodzie pokazanym na poprzednim listingu.
W tej implementacji połączono obie metody — ustawiono




                                                                      ZAPAMIĘTYWANIE USTAWIEŃ UŻYTKOWNIKÓW
wartość na pusty ciąg znaków i datę wygaśnięcia pliku
cookie w przeszłości. Wynik działania skryptu pokazano
na rysunku 5.4 — przeglądarka próbuje usunąć plik cookie
poprzez ustawienie daty jego wygaśnięcia na określony
czas (w przeszłości, a zatem plik cookie przestaje istnieć).




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

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

Usuwanie plików cookie (deletecookie.php)



                                                                     171
Udostępnianie plików cookie dla wielu domen
ROZDZIAŁ 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. Trzeba
                                        użyć argumentu o dodatniej wartości — na przykład 1.



                                       Udostępnianie plików cookie
ZAPAMIĘTYWANIE USTAWIEŃ UŻYTKOWNIKÓW




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


                                       Częścią nagłówka Set-Cookie wysyłanego przez serwer
                                       jest domena, która ma dostęp do tego pliku cookie. Jeśli
                                       wartość ta nie zostanie określona jawnie, domyślnie przyj-
                                       muje się domenę, z której wysłano plik cookie. Próba
                                       ustawienia 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.5
                                       widać, że taką możliwość miały już stare przeglądarki
                                       Netscape 4.x).

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

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



                     172
Udostępnianie plików cookie dla wielu domen




                                                                     ROZDZIAŁ 5
                                                                     ZAPAMIĘTYWANIE USTAWIEŃ UŻYTKOWNIKÓW
Rysunek 5.5. Nawet w przeglądarce Netscape 4.x można
zablokować 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.com
i ssl.przyklad.com. Sytuacja dotyczy dużych witryn WWW
z 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ą


                                                                    173
Sprawdzanie, czy klient obsługuje pliki cookie
ROZDZIAŁ 5


                                       miały dostęp wszystkie domeny trzeciego poziomu domeny
                                       przyklad.com. Jest jednak jedno „ale”. Strony umieszczone
                                       w domenie http://przyklad.com nie będą miały dostępu do
                                       tego 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.
ZAPAMIĘTYWANIE USTAWIEŃ UŻYTKOWNIKÓW




                                       Sprawdzanie, czy klient
                                       obsł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 odpowiedzi
                                       HTTP. W następnym żądaniu, jeśli użytkownik zaak-
                                       ceptuje plik cookie, klient przesyła go z powrotem na
                                       serwer. Z tego powodu wywołanie funkcji setcookie()
                                       i późniejsze sprawdzenie zawartości tablicy $_COOKIE nie
                                       zadział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);


                     174
Sprawdzanie, czy klient obsługuje pliki cookie




                                                                               ROZDZIAŁ 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: ' .




                                                                               ZAPAMIĘTYWANIE USTAWIEŃ UŻYTKOWNIKÓW
     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, czy
operacja zakończyła się sukcesem.

W zaprezentowanym powyżej kodzie ustawiono dwa pliki
cookie — jeden tymczasowy i drugi trwały — ponieważ
niektóre przeglądarki można tak skonfigurować, że jeden
typ 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ą funkcji
header() oraz nagłówka HTTP Location.

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




                                                                              175
Zapisywanie wielu danych w jednym pliku cookie
ROZDZIAŁ 5



                                       Zapisywanie wielu danych
                                       w jednym pliku cookie
                                        setcookie('cookiedata', serialize($cookiedata)


                                       Zazwyczaj w pliku cookie jest ustawiona jedna wartość
ZAPAMIĘTYWANIE USTAWIEŃ UŻYTKOWNIKÓW




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

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



                     176
Zapisywanie wielu danych w jednym pliku cookie




                                                                           ROZDZIAŁ 5
          time() + 30*24*60*60);
    }

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




                                                                           ZAPAMIĘTYWANIE USTAWIEŃ UŻYTKOWNIKÓW
        }
      } 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 plik
cookie 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.
                                                                          177
Zapisywanie ustawień językowych użytkownika
ROZDZIAŁ 5


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

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

                                            if (isset($_GET['step']) && $_GET['step'] == '2')
                                            {
ZAPAMIĘTYWANIE USTAWIEŃ UŻYTKOWNIKÓW




                                                $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żytkownika
                                        setcookie('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, na
                                       przykł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,
                     178
Zapisywanie ustawień językowych użytkownika




                                                                                   ROZDZIAŁ 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-




                                                                                   ZAPAMIĘTYWANIE USTAWIEŃ UŻYTKOWNIKÓW
      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.php
napisany w określonej wersji językowej. W tym pliku prze-
chowywany jest kod z listingu zamieszczonego na początku
tego podrozdziału. Instrukcja sprawdza, czy już ustawiono
plik cookie dla wersji językowej, a jeśli nie — ustawia plik
cookie dla bieżącego katalogu (odczytanego za pomocą
odwołania do elementu $_SERVER['PHP_SELF']).
                                                                                  179
Zapisywanie ustawień językowych użytkownika
ROZDZIAŁ 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)
ZAPAMIĘTYWANIE USTAWIEŃ UŻYTKOWNIKÓW




                                        UWAGA
                                        Jest bardzo istotne, aby ustawić ścieżkę pliku cookie na
                                        główny katalog serwera WWW. W innym przypadku warto-
                                        ścią domyślną ścieżki będzie katalog bieżący i plik będzie
                                        mó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ć, czy
                                       ustawiono 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 trzeba
                                       wprowadzić następujący kod:

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




                     180
Sesje




                                                                ROZDZIAŁ 5
Sesje
Sesja to nic innego jak wizyta użytkownika na stronie
WWW. Użytkownik klika jakieś łącza, przegląda niektóre
strony i wychodzi. Działania użytkownika w witrynie
WWW definiują sesję. Jeśli użytkownik nie zażąda danych
z witryny WWW przez pewien czas, na przykład 20 mi-




                                                                ZAPAMIĘTYWANIE USTAWIEŃ UŻYTKOWNIKÓW
nut, sesja kończy się.

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

Po utworzeniu sesji PHP generuje jej identyfikator w posta-
ci długiego ciągu znaków. Następnie tworzy zapis w pliku
lub bazie danych dotyczący określonej sesji. Po wykonaniu
tych 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ć przekazywany
pomię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ą niepotrzebnie
przesyłane istotne dane.

Konfiguracja mechanizmu sesji języka PHP jest w całości
zapisana w sekcji [session] pliku konfiguracyjnego php.ini.
Domyślne ustawienia nie pasują do wszystkich zastoso-
wań, dlatego w kolejnych podrozdziałach opisano kilka
możliwych konfiguracji.
                                                               181
Gdzie należy zapisywać sesje?
ROZDZIAŁ 5



                                       Gdzie należy zapisywać sesje?
                                       Zazwyczaj dane sesji są zapisywane w plikach. Lokalizację
                                       tych plików ustawia się za pomocą dyrektywy pliku php.ini
                                       session.save_path. Oczywiście katalog ustawiony za po-
                                       mocą tej dyrektywy musi po pierwsze istnieć, a po drugie
                                       proces PHP (zwykle proces serwera WWW) musi mieć
ZAPAMIĘTYWANIE USTAWIEŃ UŻYTKOWNIKÓW




                                       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 za
                                       tym idzie dużej liczby sesji, interpreter PHP nie powinien
                                       umieszczać 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 danych
                                       sesji 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. Aby
                                       mechanizm sesji PHP mógł zapisywać dane w podkata-
                                       logach, trzeba je wcześniej utworzyć. Do tego celu służy
                                       skrypt mod_files.sh w katalogu ext/sessions.

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




                     182
W jaki sposób zachować stan sesji?




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




                                                                   ZAPAMIĘTYWANIE USTAWIEŃ UŻYTKOWNIKÓW
Najprościej można zaimplementować ten mechanizm za
pomocą plików cookie. PHP przesyła do klienta plik cookie
o 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ć pewne
zagrożenie (na przykład modyfikowanie sesji — ang. session
fixation, lub przechwytywanie sesji — ang. session hijac-
king), ale jest dość praktyczne. Wykorzystują je wszyst-
kie znane witryny e-commerce, na przykład Amazon. Jeśli
odwiedzimy ich witrynę WWW i załadujemy stronę, iden-
tyfikator sesji zostanie automatycznie dołączony na końcu
adresu URL.
                                                                  183
Aktywacja sesji
ROZDZIAŁ 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 automatycznie
                                       włączona dla binarnych dystrybucji przeznaczonych dla
                                       systemów Windows i Mac OS X.

                                       Można również zezwolić na przekazywanie w adresach
ZAPAMIĘTYWANIE USTAWIEŃ UŻYTKOWNIKÓW




                                       URL tylko plików cookie, bez identyfikatorów sesji. Do
                                       tego 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ć je
                                        w 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) trzeba
                                        jednak wziąć pod uwagę, że niektórzy odwiedzający (poten-
                                        cjalni klienci!) nie włączą obsługi plików cookie. W takim
                                        przypadku sesje gwarantują wygodny sposób pokonania tego
                                        ograniczenia.



                                       Aktywacja sesji
                                        session_start()


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

                     184
Czytanie i zapisywanie sesji




                                                                      ROZDZIAŁ 5
Ponieważ operacja ta może wymagać przesłania plików
cookie, 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 pliku
      php.ini session.auto_start = 1,
      aktywacja sesji na poziomie skryptu, za pomocą funkcji




                                                                      ZAPAMIĘTYWANIE USTAWIEŃ UŻYTKOWNIKÓW
      session_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ż dane
są zapisane po stronie serwera, można zapisać dane sesji
i odczytać je już w następnej instrukcji PHP bez konieczno-
ści transmisji, tak jak to było w przypadku plików cookie.
                                                                     185
Zamykanie sesji
ROZDZIAŁ 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.
ZAPAMIĘTYWANIE USTAWIEŃ UŻYTKOWNIKÓW




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



                                       Zamykanie sesji
                                        session_destroy()


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

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

                     186
Modyfikacje identyfikatora sesji




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

Usuwanie wszystkich danych sesji (session_destroy.php)




Modyfikacje




                                                                                 ZAPAMIĘTYWANIE USTAWIEŃ UŻYTKOWNIKÓW
identyfikatora sesji
 session_regenerate_id()


Jednym ze znanych ataków przeciwko witrynom WWW
zabezpieczonych za pomocą sesji jest przechwycenie iden-
tyfikatora sesji użytkownika (na przykład w wyniku analizy
zapisów HTTP_REFERER w żądaniach HTTP), a następnie
wykorzystanie 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 gdy
użytkownik się zaloguje. Przykładowo w witrynie Amazon
użytkownicy, którzy zostali wcześniej uwierzytelnieni za
pomocą 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)
                                                                                187
Tworzenie dynamicznych łączy z obsługą sesji
ROZDZIAŁ 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 zamieszczonym
                                       wcześniej kodzie, gdzie za pomocą funkcji session_id()
                                       odczytano stary i bieżący identyfikator sesji. Przykładowy
                                       wynik działania tego skryptu pokazano na rysunku 5.7.
ZAPAMIĘTYWANIE USTAWIEŃ UŻYTKOWNIKÓW




                                       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 łączy
                                       z obsługą sesji
                                        $name = urlencode(session_name());
                                        $id = urlencode(session_id());
                                        echo "<a href="page.php?$name=$id">dynamiczne
                                        łącze</a>";



                     188
Tworzenie dynamicznych łączy z obsługą sesji




                                                                     ROZDZIAŁ 5
Zastosowanie ustawienia session.use_trans_sid w celu
automatycznej aktualizacji wszystkich łączy w taki sposób,
by zawierały identyfikatory sesji, to dobry pomysł, jednak
sposó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,




                                                                     ZAPAMIĘTYWANIE USTAWIEŃ UŻYTKOWNIKÓW
    session_id() — zwraca bieżący identyfikator sesji.

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

Oto przykładowy wynik działania zamieszczonego wyżej
kodu:

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


 WSKAZÓWKA
 Kiedy korzystamy z formularzy HTML, PHP automatycznie
 dołą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" />";
    ?>



                                                                    189
Implementacja własnego mechanizmu zarządzania sesjami
ROZDZIAŁ 5



                                       Implementacja własnego
                                       mechanizmu zarządzania
                                       sesjami
                                        session_set_save_handler(
                                            'sess_open', 'sess_close', 'sess_read',
ZAPAMIĘTYWANIE USTAWIEŃ UŻYTKOWNIKÓW




                                        '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 sesji
                                       w 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 konsekwentnie
                                       stosować 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 tym
                                       podrozdziale 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 baz
                                       danych w PHP można znaleźć w rozdziale 7.).

                     190
Implementacja własnego mechanizmu zarządzania sesjami




                                                                   ROZDZIAŁ 5
Funkcję PHP session_set_save_handler() można wy-
korzystać do zdefiniowania własnych funkcji dla sześciu
operacji wewnętrznie wykonywanych przez PHP:
    otwierania sesji,
    zamykania sesji,
    odczytywania zmiennej sesji,




                                                                   ZAPAMIĘTYWANIE USTAWIEŃ UŻYTKOWNIKÓW
    zapisywania zmiennej sesji,
    niszczenia sesji,
    porządkowania (tzw. odśmiecania — ang. garbage
    collection — polegającego, na przykład, na usuwaniu
    starych danych sesji z bazy danych).

Kod dla wszystkich tych sześciu operacji, który odczytuje
i 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ższym
listingu za pomocą funkcji require_once. Po wykonaniu
tych operacji można wykorzystywać sesje w standardowy
sposó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() {

                                                                  191
Implementacja własnego mechanizmu zarządzania sesjami
ROZDZIAŁ 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() {
ZAPAMIĘTYWANIE USTAWIEŃ UŻYTKOWNIKÓW




                                            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
Implementacja własnego mechanizmu zarządzania sesjami




                                                                  ROZDZIAŁ 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))




                                                                  ZAPAMIĘTYWANIE USTAWIEŃ UŻYTKOWNIKÓW
    );
    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);
                                                                 193
Tworzenie zabezpieczonego obszaru z wykorzystaniem sesji
ROZDZIAŁ 5


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

                                          session_set_save_handler(
                                            'sess_open', 'sess_close', 'sess_read',
ZAPAMIĘTYWANIE USTAWIEŃ UŻYTKOWNIKÓW




                                            '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 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
Tworzenie zabezpieczonego obszaru z wykorzystaniem sesji




                                                                      ROZDZIAŁ 5
                                                                      ZAPAMIĘTYWANIE USTAWIEŃ UŻYTKOWNIKÓW
Rysunek 5.8. Dane sesji są teraz zapisane w bazie danych

Sesje to doskonały sposób zabezpieczenia wydzielonych
częś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 stronach
wystarczy sprawdzić, czy zdefiniowano tę zmienną.

Najpierw sprawdzimy, czy zdefiniowano zmienną sesji.
Kod zamieszczony na początku tego podrozdziału należy
włą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śniej
kod, 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

                                                                     195
Tworzenie zabezpieczonego obszaru z wykorzystaniem sesji
ROZDZIAŁ 5
ZAPAMIĘTYWANIE USTAWIEŃ UŻYTKOWNIKÓW




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

                                       hasła). Jak można zobaczyć, adres URL jest podany jako
                                       parametr GET, a zatem, jeśli go zdefiniowano, kod skryptu
                                       logowania przekieruje użytkownika do strony, z której
                                       wysł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 zamieszczony
                                       na dwóch 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'


Jeśli wykorzystanie uwierzytelniania z mechanizmem za-




                                                                       ZAPAMIĘTYWANIE USTAWIEŃ UŻYTKOWNIKÓW
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órych
plików lub katalogów. Na przykład użytkownicy serwera
Apache mogą wykorzystać pliki .htaccess. Pod adresem
http://apache-server.com/tutorials/ATusing-htaccess.html
można znaleźć sporo informacji na ten temat. Serwer
Microsoft IIS jest wyposażony w narzędzie z graficznym
interfejsem użytkownika do definiowania praw dostępu,
a zatem również dla tego serwera można zdefiniować
podobny mechanizm.

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




                                                                      197
Tworzenie zabezpieczonego obszaru bez korzystania z sesji
ROZDZIAŁ 5


                                        <!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)
ZAPAMIĘTYWANIE USTAWIEŃ UŻYTKOWNIKÓW




                                       Jednym z rozwiązań, które w dużym stopniu jest niezależne
                                       od platformy, jest wykorzystanie uwierzytelniania HTTP.
                                       W przypadku przesłania kodu statusu HTTP 401 (nie-
                                       uprawniony użytkownik) przeglądarka wyświetli pytanie
                                       o nazwę użytkownika i hasło. Informacje te są później
                                       dostępne w elementach tablicy superglobalnej $_SERVER-
                                         ['PHP_AUTH_USER'] oraz $_SERVER['PHP_AUTH_PW'], ale
                                       jedynie wtedy, gdy PHP działa jako moduł serwera. Nie
                                       są 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ższym
                                       listingu. Okno dialogowe z pytaniem o nazwę użytkow-
                                       nika i hasło pokazano na rysunku 5.10.




                     198
Tworzenie zabezpieczonego obszaru bez korzystania z sesji




                                                                        ROZDZIAŁ 5
                                                                        ZAPAMIĘTYWANIE USTAWIEŃ UŻYTKOWNIKÓW
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 zabezpieczania
    stron PHP,
    pakiet HTTP_Session bazuje na mechanizmie obsługi
    sesji języka PHP, ale oferuje obiektowy dostęp do infor-
    macji dotyczących sesji.




                                                                       199

Weitere ähnliche Inhalte

Was ist angesagt?

PHP. 101 praktycznych skryptów. Wydanie II
PHP. 101 praktycznych skryptów. Wydanie IIPHP. 101 praktycznych skryptów. Wydanie II
PHP. 101 praktycznych skryptów. Wydanie IIWydawnictwo Helion
 
Zwiększ szybkość! Optymalizacja serwisów internetowych
Zwiększ szybkość! Optymalizacja serwisów internetowychZwiększ szybkość! Optymalizacja serwisów internetowych
Zwiększ szybkość! Optymalizacja serwisów internetowychWydawnictwo Helion
 
Po prostu PHP. Techniki zaawansowane
Po prostu PHP. Techniki zaawansowanePo prostu PHP. Techniki zaawansowane
Po prostu PHP. Techniki zaawansowaneWydawnictwo Helion
 
PHP5, Apache i MySQL. Od podstaw
PHP5, Apache i MySQL. Od podstawPHP5, Apache i MySQL. Od podstaw
PHP5, Apache i MySQL. Od podstawWydawnictwo Helion
 
PHP i MySQL. Tworzenie stron WWW. Wydanie drugie. Vademecum profesjonalisty
PHP i MySQL. Tworzenie stron WWW. Wydanie drugie. Vademecum profesjonalistyPHP i MySQL. Tworzenie stron WWW. Wydanie drugie. Vademecum profesjonalisty
PHP i MySQL. Tworzenie stron WWW. Wydanie drugie. Vademecum profesjonalistyWydawnictwo Helion
 
PHP, MySQL i Apache dla każdego. Wydanie II
PHP, MySQL i Apache dla każdego. Wydanie IIPHP, MySQL i Apache dla każdego. Wydanie II
PHP, MySQL i Apache dla każdego. Wydanie IIWydawnictwo Helion
 
Empathy optymalizacja postgre_sql
Empathy optymalizacja postgre_sqlEmpathy optymalizacja postgre_sql
Empathy optymalizacja postgre_sqlSpodek 2.0
 
100 sposobów na serwery Windows
100 sposobów na serwery Windows100 sposobów na serwery Windows
100 sposobów na serwery WindowsWydawnictwo Helion
 
Po prostu własny serwer internetowy
Po prostu własny serwer internetowyPo prostu własny serwer internetowy
Po prostu własny serwer internetowyWydawnictwo Helion
 
Java w komercyjnych usługach sieciowych. Księga eksperta
Java w komercyjnych usługach sieciowych. Księga ekspertaJava w komercyjnych usługach sieciowych. Księga eksperta
Java w komercyjnych usługach sieciowych. Księga ekspertaWydawnictwo Helion
 
Serwisy internetowe. Programowanie
Serwisy internetowe. ProgramowanieSerwisy internetowe. Programowanie
Serwisy internetowe. ProgramowanieWydawnictwo Helion
 
Internet. Ilustrowany przewodnik
Internet. Ilustrowany przewodnikInternet. Ilustrowany przewodnik
Internet. Ilustrowany przewodnikWydawnictwo Helion
 
Adobe Dreamweaver CS3 z ASP, ColdFusion i PHP. Oficjalny podręcznik
Adobe Dreamweaver CS3 z ASP, ColdFusion i PHP. Oficjalny podręcznikAdobe Dreamweaver CS3 z ASP, ColdFusion i PHP. Oficjalny podręcznik
Adobe Dreamweaver CS3 z ASP, ColdFusion i PHP. Oficjalny podręcznikWydawnictwo Helion
 
PHP, Microsoft IIS i SQL Server. Projektowanie i programowanie baz danych
PHP, Microsoft IIS i SQL Server. Projektowanie i programowanie baz danychPHP, Microsoft IIS i SQL Server. Projektowanie i programowanie baz danych
PHP, Microsoft IIS i SQL Server. Projektowanie i programowanie baz danychWydawnictwo Helion
 
JavaScript. Zaawansowane programowanie
JavaScript. Zaawansowane programowanieJavaScript. Zaawansowane programowanie
JavaScript. Zaawansowane programowanieWydawnictwo Helion
 

Was ist angesagt? (20)

PHP. 101 praktycznych skryptów. Wydanie II
PHP. 101 praktycznych skryptów. Wydanie IIPHP. 101 praktycznych skryptów. Wydanie II
PHP. 101 praktycznych skryptów. Wydanie II
 
Zwiększ szybkość! Optymalizacja serwisów internetowych
Zwiększ szybkość! Optymalizacja serwisów internetowychZwiększ szybkość! Optymalizacja serwisów internetowych
Zwiększ szybkość! Optymalizacja serwisów internetowych
 
Po prostu PHP. Techniki zaawansowane
Po prostu PHP. Techniki zaawansowanePo prostu PHP. Techniki zaawansowane
Po prostu PHP. Techniki zaawansowane
 
PHP5, Apache i MySQL. Od podstaw
PHP5, Apache i MySQL. Od podstawPHP5, Apache i MySQL. Od podstaw
PHP5, Apache i MySQL. Od podstaw
 
PHP i MySQL. Tworzenie stron WWW. Wydanie drugie. Vademecum profesjonalisty
PHP i MySQL. Tworzenie stron WWW. Wydanie drugie. Vademecum profesjonalistyPHP i MySQL. Tworzenie stron WWW. Wydanie drugie. Vademecum profesjonalisty
PHP i MySQL. Tworzenie stron WWW. Wydanie drugie. Vademecum profesjonalisty
 
PHP, MySQL i Apache dla każdego. Wydanie II
PHP, MySQL i Apache dla każdego. Wydanie IIPHP, MySQL i Apache dla każdego. Wydanie II
PHP, MySQL i Apache dla każdego. Wydanie II
 
Empathy optymalizacja postgre_sql
Empathy optymalizacja postgre_sqlEmpathy optymalizacja postgre_sql
Empathy optymalizacja postgre_sql
 
Apache. Rozmówki
Apache. RozmówkiApache. Rozmówki
Apache. Rozmówki
 
Pajączek 5 NxG
Pajączek  5 NxGPajączek  5 NxG
Pajączek 5 NxG
 
100 sposobów na serwery Windows
100 sposobów na serwery Windows100 sposobów na serwery Windows
100 sposobów na serwery Windows
 
PHP5. Praktyczny kurs
PHP5. Praktyczny kursPHP5. Praktyczny kurs
PHP5. Praktyczny kurs
 
JavaScript i DHTML. Receptury
JavaScript i DHTML. RecepturyJavaScript i DHTML. Receptury
JavaScript i DHTML. Receptury
 
Po prostu własny serwer internetowy
Po prostu własny serwer internetowyPo prostu własny serwer internetowy
Po prostu własny serwer internetowy
 
Java w komercyjnych usługach sieciowych. Księga eksperta
Java w komercyjnych usługach sieciowych. Księga ekspertaJava w komercyjnych usługach sieciowych. Księga eksperta
Java w komercyjnych usługach sieciowych. Księga eksperta
 
Serwisy internetowe. Programowanie
Serwisy internetowe. ProgramowanieSerwisy internetowe. Programowanie
Serwisy internetowe. Programowanie
 
Internet. Ilustrowany przewodnik
Internet. Ilustrowany przewodnikInternet. Ilustrowany przewodnik
Internet. Ilustrowany przewodnik
 
PHP. Praktyczne wprowadzenie
PHP. Praktyczne wprowadzeniePHP. Praktyczne wprowadzenie
PHP. Praktyczne wprowadzenie
 
Adobe Dreamweaver CS3 z ASP, ColdFusion i PHP. Oficjalny podręcznik
Adobe Dreamweaver CS3 z ASP, ColdFusion i PHP. Oficjalny podręcznikAdobe Dreamweaver CS3 z ASP, ColdFusion i PHP. Oficjalny podręcznik
Adobe Dreamweaver CS3 z ASP, ColdFusion i PHP. Oficjalny podręcznik
 
PHP, Microsoft IIS i SQL Server. Projektowanie i programowanie baz danych
PHP, Microsoft IIS i SQL Server. Projektowanie i programowanie baz danychPHP, Microsoft IIS i SQL Server. Projektowanie i programowanie baz danych
PHP, Microsoft IIS i SQL Server. Projektowanie i programowanie baz danych
 
JavaScript. Zaawansowane programowanie
JavaScript. Zaawansowane programowanieJavaScript. Zaawansowane programowanie
JavaScript. Zaawansowane programowanie
 

Andere mochten auch

Real World Adobe Photoshop CS2. Edycja polska
Real World Adobe Photoshop CS2. Edycja polskaReal World Adobe Photoshop CS2. Edycja polska
Real World Adobe Photoshop CS2. Edycja polskaWydawnictwo Helion
 
Macromedia Flash 8 Professional. Księga eksperta
Macromedia Flash 8 Professional. Księga ekspertaMacromedia Flash 8 Professional. Księga eksperta
Macromedia Flash 8 Professional. Księga ekspertaWydawnictwo Helion
 
Macromedia Fireworks 8. Oficjalny podręcznik
Macromedia Fireworks 8. Oficjalny podręcznikMacromedia Fireworks 8. Oficjalny podręcznik
Macromedia Fireworks 8. Oficjalny podręcznikWydawnictwo Helion
 
Jak założyć skuteczny i dochodowy sklep internetowy
Jak założyć skuteczny i dochodowy sklep internetowyJak założyć skuteczny i dochodowy sklep internetowy
Jak założyć skuteczny i dochodowy sklep internetowyWydawnictwo Helion
 
Rozbudowa i naprawa systemu Windows
Rozbudowa i naprawa systemu WindowsRozbudowa i naprawa systemu Windows
Rozbudowa i naprawa systemu WindowsWydawnictwo Helion
 
Excel 2003. Programowanie. Zapiski programisty
Excel 2003. Programowanie. Zapiski programistyExcel 2003. Programowanie. Zapiski programisty
Excel 2003. Programowanie. Zapiski programistyWydawnictwo Helion
 
101 praktycznych skryptów na stronę WWW. Wydanie II
101 praktycznych skryptów na stronę WWW. Wydanie II101 praktycznych skryptów na stronę WWW. Wydanie II
101 praktycznych skryptów na stronę WWW. Wydanie IIWydawnictwo Helion
 
Flash 8. Techniki zaawansowane. Klatka po klatce
Flash 8. Techniki zaawansowane. Klatka po klatceFlash 8. Techniki zaawansowane. Klatka po klatce
Flash 8. Techniki zaawansowane. Klatka po klatceWydawnictwo Helion
 
Real World Adobe Photoshop CS2. Edycja polska
Real World Adobe Photoshop CS2. Edycja polskaReal World Adobe Photoshop CS2. Edycja polska
Real World Adobe Photoshop CS2. Edycja polskaWydawnictwo Helion
 
Macromedia Flash 8. Oficjalny podręcznik
Macromedia Flash 8. Oficjalny podręcznikMacromedia Flash 8. Oficjalny podręcznik
Macromedia Flash 8. Oficjalny podręcznikWydawnictwo Helion
 
Sieci komputerowe. Od ogółu do szczegółu z internetem w tle. Wydanie III
Sieci komputerowe. Od ogółu do szczegółu z internetem w tle. Wydanie IIISieci komputerowe. Od ogółu do szczegółu z internetem w tle. Wydanie III
Sieci komputerowe. Od ogółu do szczegółu z internetem w tle. Wydanie IIIWydawnictwo Helion
 
Photoshop CS2/CS2 PL. Prosto do celu
Photoshop CS2/CS2 PL. Prosto do celuPhotoshop CS2/CS2 PL. Prosto do celu
Photoshop CS2/CS2 PL. Prosto do celuWydawnictwo Helion
 
Perl. Zaawansowane programowanie. Wydanie II
Perl. Zaawansowane programowanie. Wydanie IIPerl. Zaawansowane programowanie. Wydanie II
Perl. Zaawansowane programowanie. Wydanie IIWydawnictwo Helion
 

Andere mochten auch (13)

Real World Adobe Photoshop CS2. Edycja polska
Real World Adobe Photoshop CS2. Edycja polskaReal World Adobe Photoshop CS2. Edycja polska
Real World Adobe Photoshop CS2. Edycja polska
 
Macromedia Flash 8 Professional. Księga eksperta
Macromedia Flash 8 Professional. Księga ekspertaMacromedia Flash 8 Professional. Księga eksperta
Macromedia Flash 8 Professional. Księga eksperta
 
Macromedia Fireworks 8. Oficjalny podręcznik
Macromedia Fireworks 8. Oficjalny podręcznikMacromedia Fireworks 8. Oficjalny podręcznik
Macromedia Fireworks 8. Oficjalny podręcznik
 
Jak założyć skuteczny i dochodowy sklep internetowy
Jak założyć skuteczny i dochodowy sklep internetowyJak założyć skuteczny i dochodowy sklep internetowy
Jak założyć skuteczny i dochodowy sklep internetowy
 
Rozbudowa i naprawa systemu Windows
Rozbudowa i naprawa systemu WindowsRozbudowa i naprawa systemu Windows
Rozbudowa i naprawa systemu Windows
 
Excel 2003. Programowanie. Zapiski programisty
Excel 2003. Programowanie. Zapiski programistyExcel 2003. Programowanie. Zapiski programisty
Excel 2003. Programowanie. Zapiski programisty
 
101 praktycznych skryptów na stronę WWW. Wydanie II
101 praktycznych skryptów na stronę WWW. Wydanie II101 praktycznych skryptów na stronę WWW. Wydanie II
101 praktycznych skryptów na stronę WWW. Wydanie II
 
Flash 8. Techniki zaawansowane. Klatka po klatce
Flash 8. Techniki zaawansowane. Klatka po klatceFlash 8. Techniki zaawansowane. Klatka po klatce
Flash 8. Techniki zaawansowane. Klatka po klatce
 
Real World Adobe Photoshop CS2. Edycja polska
Real World Adobe Photoshop CS2. Edycja polskaReal World Adobe Photoshop CS2. Edycja polska
Real World Adobe Photoshop CS2. Edycja polska
 
Macromedia Flash 8. Oficjalny podręcznik
Macromedia Flash 8. Oficjalny podręcznikMacromedia Flash 8. Oficjalny podręcznik
Macromedia Flash 8. Oficjalny podręcznik
 
Sieci komputerowe. Od ogółu do szczegółu z internetem w tle. Wydanie III
Sieci komputerowe. Od ogółu do szczegółu z internetem w tle. Wydanie IIISieci komputerowe. Od ogółu do szczegółu z internetem w tle. Wydanie III
Sieci komputerowe. Od ogółu do szczegółu z internetem w tle. Wydanie III
 
Photoshop CS2/CS2 PL. Prosto do celu
Photoshop CS2/CS2 PL. Prosto do celuPhotoshop CS2/CS2 PL. Prosto do celu
Photoshop CS2/CS2 PL. Prosto do celu
 
Perl. Zaawansowane programowanie. Wydanie II
Perl. Zaawansowane programowanie. Wydanie IIPerl. Zaawansowane programowanie. Wydanie II
Perl. Zaawansowane programowanie. Wydanie II
 

Ähnlich wie PHP. Rozmówki

PHP, MySQL i Apache dla każdego. Wydanie III
PHP, MySQL i Apache dla każdego. Wydanie IIIPHP, MySQL i Apache dla każdego. Wydanie III
PHP, MySQL i Apache dla każdego. Wydanie IIIWydawnictwo Helion
 
ASP.NET 3.5 dla programistów PHP
ASP.NET 3.5 dla programistów PHPASP.NET 3.5 dla programistów PHP
ASP.NET 3.5 dla programistów PHPWydawnictwo Helion
 
PHP5. Zaawansowane programowanie
PHP5. Zaawansowane programowaniePHP5. Zaawansowane programowanie
PHP5. Zaawansowane programowanieWydawnictwo Helion
 
PHP i MySQL. Aplikacje bazodanowe
PHP i MySQL. Aplikacje bazodanowePHP i MySQL. Aplikacje bazodanowe
PHP i MySQL. Aplikacje bazodanoweWydawnictwo Helion
 
ASP.NET 2.0. Gotowe rozwiązania
ASP.NET 2.0. Gotowe rozwiązaniaASP.NET 2.0. Gotowe rozwiązania
ASP.NET 2.0. Gotowe rozwiązaniaWydawnictwo Helion
 
PHP4. Zaawansowane programowanie
PHP4. Zaawansowane programowaniePHP4. Zaawansowane programowanie
PHP4. Zaawansowane programowanieWydawnictwo Helion
 
PHP i MySQL. Tworzenie sklepów internetowych. Wydanie II
PHP i MySQL. Tworzenie sklepów internetowych. Wydanie IIPHP i MySQL. Tworzenie sklepów internetowych. Wydanie II
PHP i MySQL. Tworzenie sklepów internetowych. Wydanie IIWydawnictwo Helion
 
PHP5. Obiekty, wzorce, narzędzia
PHP5. Obiekty, wzorce, narzędziaPHP5. Obiekty, wzorce, narzędzia
PHP5. Obiekty, wzorce, narzędziaWydawnictwo Helion
 
PHP i MySQL. Wprowadzenie. Wydanie II
PHP i MySQL. Wprowadzenie. Wydanie IIPHP i MySQL. Wprowadzenie. Wydanie II
PHP i MySQL. Wprowadzenie. Wydanie IIWydawnictwo Helion
 
Java. Usługi WWW. Vademecum profesjonalisty
Java. Usługi WWW. Vademecum profesjonalistyJava. Usługi WWW. Vademecum profesjonalisty
Java. Usługi WWW. Vademecum profesjonalistyWydawnictwo Helion
 

Ähnlich wie PHP. Rozmówki (19)

PHP5. Radocha z programowania
PHP5. Radocha z programowaniaPHP5. Radocha z programowania
PHP5. Radocha z programowania
 
PHP. Programowanie
PHP. ProgramowaniePHP. Programowanie
PHP. Programowanie
 
PHP, MySQL i Apache dla każdego. Wydanie III
PHP, MySQL i Apache dla każdego. Wydanie IIIPHP, MySQL i Apache dla każdego. Wydanie III
PHP, MySQL i Apache dla każdego. Wydanie III
 
ASP.NET 3.5 dla programistów PHP
ASP.NET 3.5 dla programistów PHPASP.NET 3.5 dla programistów PHP
ASP.NET 3.5 dla programistów PHP
 
PHP5 i MySQL. Biblia
PHP5 i MySQL. BibliaPHP5 i MySQL. Biblia
PHP5 i MySQL. Biblia
 
Po prostu Pajączek 5 NxG
Po prostu Pajączek 5 NxGPo prostu Pajączek 5 NxG
Po prostu Pajączek 5 NxG
 
Spring. Zapiski programisty
Spring. Zapiski programistySpring. Zapiski programisty
Spring. Zapiski programisty
 
PHP5. Zaawansowane programowanie
PHP5. Zaawansowane programowaniePHP5. Zaawansowane programowanie
PHP5. Zaawansowane programowanie
 
PHP5. Księga eksperta
PHP5. Księga ekspertaPHP5. Księga eksperta
PHP5. Księga eksperta
 
PHP i MySQL. Aplikacje bazodanowe
PHP i MySQL. Aplikacje bazodanowePHP i MySQL. Aplikacje bazodanowe
PHP i MySQL. Aplikacje bazodanowe
 
ASP.NET 2.0. Gotowe rozwiązania
ASP.NET 2.0. Gotowe rozwiązaniaASP.NET 2.0. Gotowe rozwiązania
ASP.NET 2.0. Gotowe rozwiązania
 
PHP4. Zaawansowane programowanie
PHP4. Zaawansowane programowaniePHP4. Zaawansowane programowanie
PHP4. Zaawansowane programowanie
 
Mandrake Linux
Mandrake LinuxMandrake Linux
Mandrake Linux
 
PHP i MySQL. Tworzenie sklepów internetowych. Wydanie II
PHP i MySQL. Tworzenie sklepów internetowych. Wydanie IIPHP i MySQL. Tworzenie sklepów internetowych. Wydanie II
PHP i MySQL. Tworzenie sklepów internetowych. Wydanie II
 
PHP5. Obiekty, wzorce, narzędzia
PHP5. Obiekty, wzorce, narzędziaPHP5. Obiekty, wzorce, narzędzia
PHP5. Obiekty, wzorce, narzędzia
 
Java. Sztuka programowania
Java. Sztuka programowaniaJava. Sztuka programowania
Java. Sztuka programowania
 
PHP i MySQL. Wprowadzenie. Wydanie II
PHP i MySQL. Wprowadzenie. Wydanie IIPHP i MySQL. Wprowadzenie. Wydanie II
PHP i MySQL. Wprowadzenie. Wydanie II
 
Java. Usługi WWW. Vademecum profesjonalisty
Java. Usługi WWW. Vademecum profesjonalistyJava. Usługi WWW. Vademecum profesjonalisty
Java. Usługi WWW. Vademecum profesjonalisty
 
Visual C# .NET. Encyklopedia
Visual C# .NET. EncyklopediaVisual C# .NET. Encyklopedia
Visual C# .NET. Encyklopedia
 

Mehr von Wydawnictwo Helion

Tworzenie filmów w Windows XP. Projekty
Tworzenie filmów w Windows XP. ProjektyTworzenie filmów w Windows XP. Projekty
Tworzenie filmów w Windows XP. ProjektyWydawnictwo Helion
 
Blog, więcej niż internetowy pamiętnik
Blog, więcej niż internetowy pamiętnikBlog, więcej niż internetowy pamiętnik
Blog, więcej niż internetowy pamiętnikWydawnictwo Helion
 
Pozycjonowanie i optymalizacja stron WWW. Ćwiczenia praktyczne
Pozycjonowanie i optymalizacja stron WWW. Ćwiczenia praktycznePozycjonowanie i optymalizacja stron WWW. Ćwiczenia praktyczne
Pozycjonowanie i optymalizacja stron WWW. Ćwiczenia praktyczneWydawnictwo Helion
 
E-wizerunek. Internet jako narzędzie kreowania image&#39;u w biznesie
E-wizerunek. Internet jako narzędzie kreowania image&#39;u w biznesieE-wizerunek. Internet jako narzędzie kreowania image&#39;u w biznesie
E-wizerunek. Internet jako narzędzie kreowania image&#39;u w biznesieWydawnictwo Helion
 
Microsoft Visual C++ 2008. Tworzenie aplikacji dla Windows
Microsoft Visual C++ 2008. Tworzenie aplikacji dla WindowsMicrosoft Visual C++ 2008. Tworzenie aplikacji dla Windows
Microsoft Visual C++ 2008. Tworzenie aplikacji dla WindowsWydawnictwo Helion
 
Co potrafi Twój iPhone? Podręcznik użytkownika. Wydanie II
Co potrafi Twój iPhone? Podręcznik użytkownika. Wydanie IICo potrafi Twój iPhone? Podręcznik użytkownika. Wydanie II
Co potrafi Twój iPhone? Podręcznik użytkownika. Wydanie IIWydawnictwo Helion
 
Makrofotografia. Magia szczegółu
Makrofotografia. Magia szczegółuMakrofotografia. Magia szczegółu
Makrofotografia. Magia szczegółuWydawnictwo Helion
 
Java. Efektywne programowanie. Wydanie II
Java. Efektywne programowanie. Wydanie IIJava. Efektywne programowanie. Wydanie II
Java. Efektywne programowanie. Wydanie IIWydawnictwo Helion
 
Ajax, JavaScript i PHP. Intensywny trening
Ajax, JavaScript i PHP. Intensywny treningAjax, JavaScript i PHP. Intensywny trening
Ajax, JavaScript i PHP. Intensywny treningWydawnictwo Helion
 
PowerPoint 2007 PL. Seria praktyk
PowerPoint 2007 PL. Seria praktykPowerPoint 2007 PL. Seria praktyk
PowerPoint 2007 PL. Seria praktykWydawnictwo Helion
 
Serwisy społecznościowe. Budowa, administracja i moderacja
Serwisy społecznościowe. Budowa, administracja i moderacjaSerwisy społecznościowe. Budowa, administracja i moderacja
Serwisy społecznościowe. Budowa, administracja i moderacjaWydawnictwo Helion
 

Mehr von Wydawnictwo Helion (20)

Tworzenie filmów w Windows XP. Projekty
Tworzenie filmów w Windows XP. ProjektyTworzenie filmów w Windows XP. Projekty
Tworzenie filmów w Windows XP. Projekty
 
Blog, więcej niż internetowy pamiętnik
Blog, więcej niż internetowy pamiętnikBlog, więcej niż internetowy pamiętnik
Blog, więcej niż internetowy pamiętnik
 
Access w biurze i nie tylko
Access w biurze i nie tylkoAccess w biurze i nie tylko
Access w biurze i nie tylko
 
Pozycjonowanie i optymalizacja stron WWW. Ćwiczenia praktyczne
Pozycjonowanie i optymalizacja stron WWW. Ćwiczenia praktycznePozycjonowanie i optymalizacja stron WWW. Ćwiczenia praktyczne
Pozycjonowanie i optymalizacja stron WWW. Ćwiczenia praktyczne
 
E-wizerunek. Internet jako narzędzie kreowania image&#39;u w biznesie
E-wizerunek. Internet jako narzędzie kreowania image&#39;u w biznesieE-wizerunek. Internet jako narzędzie kreowania image&#39;u w biznesie
E-wizerunek. Internet jako narzędzie kreowania image&#39;u w biznesie
 
Microsoft Visual C++ 2008. Tworzenie aplikacji dla Windows
Microsoft Visual C++ 2008. Tworzenie aplikacji dla WindowsMicrosoft Visual C++ 2008. Tworzenie aplikacji dla Windows
Microsoft Visual C++ 2008. Tworzenie aplikacji dla Windows
 
Co potrafi Twój iPhone? Podręcznik użytkownika. Wydanie II
Co potrafi Twój iPhone? Podręcznik użytkownika. Wydanie IICo potrafi Twój iPhone? Podręcznik użytkownika. Wydanie II
Co potrafi Twój iPhone? Podręcznik użytkownika. Wydanie II
 
Makrofotografia. Magia szczegółu
Makrofotografia. Magia szczegółuMakrofotografia. Magia szczegółu
Makrofotografia. Magia szczegółu
 
Windows PowerShell. Podstawy
Windows PowerShell. PodstawyWindows PowerShell. Podstawy
Windows PowerShell. Podstawy
 
Java. Efektywne programowanie. Wydanie II
Java. Efektywne programowanie. Wydanie IIJava. Efektywne programowanie. Wydanie II
Java. Efektywne programowanie. Wydanie II
 
JavaScript. Pierwsze starcie
JavaScript. Pierwsze starcieJavaScript. Pierwsze starcie
JavaScript. Pierwsze starcie
 
Ajax, JavaScript i PHP. Intensywny trening
Ajax, JavaScript i PHP. Intensywny treningAjax, JavaScript i PHP. Intensywny trening
Ajax, JavaScript i PHP. Intensywny trening
 
PowerPoint 2007 PL. Seria praktyk
PowerPoint 2007 PL. Seria praktykPowerPoint 2007 PL. Seria praktyk
PowerPoint 2007 PL. Seria praktyk
 
Excel 2007 PL. Seria praktyk
Excel 2007 PL. Seria praktykExcel 2007 PL. Seria praktyk
Excel 2007 PL. Seria praktyk
 
Access 2007 PL. Seria praktyk
Access 2007 PL. Seria praktykAccess 2007 PL. Seria praktyk
Access 2007 PL. Seria praktyk
 
Word 2007 PL. Seria praktyk
Word 2007 PL. Seria praktykWord 2007 PL. Seria praktyk
Word 2007 PL. Seria praktyk
 
Serwisy społecznościowe. Budowa, administracja i moderacja
Serwisy społecznościowe. Budowa, administracja i moderacjaSerwisy społecznościowe. Budowa, administracja i moderacja
Serwisy społecznościowe. Budowa, administracja i moderacja
 
AutoCAD 2008 i 2008 PL
AutoCAD 2008 i 2008 PLAutoCAD 2008 i 2008 PL
AutoCAD 2008 i 2008 PL
 
Bazy danych. Pierwsze starcie
Bazy danych. Pierwsze starcieBazy danych. Pierwsze starcie
Bazy danych. Pierwsze starcie
 
Inventor. Pierwsze kroki
Inventor. Pierwsze krokiInventor. Pierwsze kroki
Inventor. Pierwsze kroki
 

PHP. Rozmówki

  • 1. IDZ DO PRZYK£ADOWY ROZDZIA£ SPIS TREŒCI PHP. Rozmówki Autor: Christian Wenz KATALOG KSI¥¯EK T³umaczenie: Rados³aw Meryk ISBN: 83-246-0324-7 KATALOG ONLINE Tytu³ orygina³u: PHP Phrasebook Format: B5, stron: 360 ZAMÓW DRUKOWANY KATALOG TWÓJ KOSZYK DODAJ DO KOSZYKA 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 CENNIK I INFORMACJE 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 ZAMÓW INFORMACJE znajduj¹ siê w jednym miejscu, praca szybko posuwa siê do przodu. O NOWOŒCIACH 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 ZAMÓW CENNIK 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 CZYTELNIA produktywnoœæ. • Operacje na ³añcuchach tekstowych FRAGMENTY KSI¥¯EK ONLINE • 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 — Wydawnictwo Helion zatem po co korzystaæ z opas³ych tomów? ul. Chopina 6 44-100 Gliwice tel. (32)230-98-63 e-mail: helion@helion.pl
  • 2. Spis treści O autorze ............................................................................11 Wprowadzenie ...................................................................13 1 Operacje na ciągach znaków ..............................................17 Porównywanie ciągów znaków ...............................................18 Sprawdzanie poprawności nazw użytkowników i haseł ...........19 Przekształcanie ciągów znaków na język HTML .......................21 Zastosowanie znaków podziału wiersza ..................................24 Szyfrowanie ciągów znaków ...................................................25 Sprawdzanie sum kontrolnych ciągów znaków .......................27 Wydzielanie podciągów znaków ...............................................29 Zabezpieczanie adresów e-mail za pomocą kodów ASCII ........30 Skanowanie sformatowanych ciągów znaków ........................35 Pobieranie szczegółowych informacji o zmiennych ..................36 Wyszukiwanie w ciągach znaków ...........................................37 Wykorzystanie wyrażeń regularnych POSIX .............................41 Wykorzystanie wyrażeń regularnych zgodnych z Perlem ..........43 Wyszukiwanie znaczników za pomocą wyrażeń regularnych ......44 Sprawdzanie poprawności pól obowiązkowych ......................45
  • 3. Spis treści Sprawdzanie poprawności liczb i danych innych typów .......... 47 Sprawdzanie poprawności adresów e-mail ............................. 49 Wyszukiwanie z zastępowaniem ................................................ 51 2 Tablice ................................................................................55 Dostęp do wszystkich elementów tablicy numerycznej .............. 57 Dostęp do wszystkich elementów tablicy asocjacyjnej ............ 59 Dostęp do wszystkich elementów tablicy zagnieżdżonej ......... 60 Przekształcanie elementów tablic na zmienne ........................ 63 Konwersja ciągów znaków na tablice ..................................... 64 Konwersja tablic na ciągi znaków ........................................... 65 Alfabetyczne sortowanie tablic ............................................... 66 Alfabetyczne sortowanie tablic asocjacyjnych ......................... 68 Sortowanie tablic zagnieżdżonych .......................................... 70 Sortowanie zagnieżdżonych tablic asocjacyjnych .................... 72 Sortowanie adresów IP (tak jak robiliby to ludzie) .................. 74 Sortowanie niestandardowe ................................................... 76 Sortowanie z wykorzystaniem znaków narodowych ............... 77 Wykonywanie operacji dla wszystkich elementów tablicy ....... 80 Filtrowanie tablic ................................................................... 83 Losowe pobieranie elementów z tablicy ................................. 84 3 Daty i godziny .....................................................................87 Wykorzystanie tekstu wewnątrz funkcji date() ........................ 90 Automatyczna lokalizacja dat ................................................. 92 Ręczna lokalizacja dat ............................................................ 96 Wykorzystanie daty bieżącej w formacie US, UK i europejskim .... 97 Formatowanie dowolnych dat ................................................ 98 Sprawdzanie poprawności dat ............................................... 99 Wykonywanie obliczeń z datami ............................................. 100 Tworzenie znaczników czasu, które można sortować ............ 101 4
  • 4. Spis treści Konwersja ciągów znaków na daty .......................................103 Określanie czasu wschodu i zachodu słońca ..........................104 Wykorzystanie dat i godzin do testów szybkości działania sprzętu lub programów .......................106 Zastosowanie pól formularzy do wyboru dat .........................108 Tworzenie samouaktualniających się pól formularzy do wyboru dat ......................................110 Obliczanie różnicy pomiędzy dwiema datami ........................112 Wykorzystanie informacji o dacie i godzinie według GMT .....115 4 Interakcje z formularzami WWW ......................................117 Przesyłanie danych formularza do bieżącego skryptu ............119 Odczyt danych formularzy .....................................................119 Magiczne cudzysłowy (apostrofy) ..........................................123 Sprawdzenie, czy przesłano formularz ...................................124 Zapisywanie danych formularzy w plikach cookie ..................126 Wypełnianie pól tekstowych i pól haseł danymi początkowymi ......................................129 Wypełnianie wielowierszowych pól tekstowych danymi początkowymi ...............................132 Domyślne wartości przełączników .........................................134 Wypełnianie pól wyboru danymi początkowymi ...................136 Wypełnianie list wyboru danymi początkowymi ....................137 Wypełnianie list wielokrotnego wyboru danymi początkowymi ..........................................139 Przetwarzanie graficznych przycisków Submit .......................142 Sprawdzanie pól obowiązkowych .........................................144 Sprawdzanie poprawności list wyboru ..................................146 Zapisywanie wszystkich danych formularza w pliku ..............149 Wysyłanie wszystkich danych formularza pocztą elektroniczną ..151 5
  • 5. Spis treści Pobieranie informacji na temat plików wgrywanych na serwer ..................................................... 153 Przenoszenie plików wgranych na serwer do bezpiecznej lokalizacji .................................. 156 5 Zapamiętywanie ustawień użytkowników — pliki cookie i sesje .....................................................159 Istota plików cookie ............................................................. 160 Tworzenie plików cookie ...................................................... 163 Odczytywanie plików cookie ................................................ 164 Pozbywanie się „magicznych” cudzysłowów (apostrofów) z plików cookie ................................................................. 166 Ustawianie daty ważności względem innej daty ................... 167 Ustawianie daty ważności specyficznej dla klienta ................ 169 Usuwanie plików cookie ...................................................... 170 Udostępnianie plików cookie dla wielu domen ..................... 172 Sprawdzanie, czy klient obsługuje pliki cookie ...................... 174 Zapisywanie wielu danych w jednym pliku cookie ................ 176 Zapisywanie ustawień językowych użytkownika ................... 178 Sesje .................................................................................... 181 Gdzie należy zapisywać sesje? .............................................. 182 W jaki sposób zachować stan sesji? ..................................... 183 Aktywacja sesji .................................................................... 184 Czytanie i zapisywanie sesji ................................................. 185 Zamykanie sesji .................................................................... 186 Modyfikacje identyfikatora sesji ............................................ 187 Tworzenie dynamicznych łączy z obsługą sesji ...................... 188 Implementacja własnego mechanizmu zarządzania sesjami .. 190 Tworzenie zabezpieczonego obszaru z wykorzystaniem sesji 194 Tworzenie zabezpieczonego obszaru bez korzystania z sesji . 197 6
  • 6. Spis treści 6 Wykorzystanie plików zapisanych w systemie plików serwera ...........................................201 Otwieranie i zamykanie plików .............................................202 Odczytywanie danych z plików .............................................206 Zapisywanie danych do pliku ................................................208 Blokowanie plików ...............................................................210 Wykorzystanie ścieżek względnych w celu uzyskania dostępu do pliku ....................................212 Unikanie niebezpiecznych pułapek związanych z dostępem do plików .......................................................213 Wykorzystanie danych w formacie CSV .................................215 Przetwarzanie plików INI ......................................................220 Odczytywanie informacji o plikach ........................................222 Kopiowanie, przenoszenie i usuwanie plików .......................225 Przeglądanie systemu plików ................................................226 Wykorzystanie strumieni w PHP ...............................................227 Wykorzystanie archiwów Bzip2 .............................................229 Zwracanie plików za pomocą żądania HTTP ..........................232 7 Tworzenie danych dynamicznych .....................................235 Nawiązywanie połączenia z bazą danych ..............................237 Nawiązywanie połączenia z bazą danych z wykorzystaniem rozszerzenia MySQLi ................................238 Wysyłanie instrukcji SQL do bazy danych MySQL ...................240 Instrukcje preparowane w MySQL-u ......................................242 Odczytywanie wyników zapytania do bazy danych MySQL ....245 Nawiązywanie połączenia z bazą danych SQLite ...................248 Wysyłanie instrukcji SQL do bazy danych SQLite ....................250 Odczytywanie wyników zapytania do bazy danych SQLite .....251 Nawiązywanie połączenia z bazą danych PostgreSQL ............253 Wysyłanie zapytań SQL do bazy danych PosgreSQL ...............255 7
  • 7. Spis treści Aktualizacja danych w PostgreSQL ....................................... 256 Odczytywanie wyników zapytania do bazy danych PostgreSQL .............................................. 257 Nawiązywanie połączenia z bazą danych Oracle .................. 259 Wysyłanie instrukcji SQL do bazy danych Oracle ................... 260 Odczytywanie wyników zapytania do bazy danych Oracle .... 263 Nawiązywanie połączenia z bazą danych MSSQL ................. 265 Przesyłanie instrukcji SQL do bazy danych MSSQL ................. 267 Odczytywanie wyników zapytania do bazy danych MSSQL ... 269 Nawiązywanie połączenia z bazą danych Firebird ................. 270 Przesyłanie instrukcji SQL do bazy danych Firebird ................ 272 Odczytywanie wyników zapytania do bazy danych Firebird .. 273 Nawiązywanie połączenia z bazami danych za pomocą PDO ....... 274 Przesyłanie instrukcji SQL za pomocą PDO ............................ 277 Odczytywanie wyników zapytań przesyłanych za pomocą PDO ..278 8 Wykorzystanie XML-a .......................................................281 Przetwarzanie XML za pomocą interfejsu SAX ...................... 282 Odczyt dokumentów XML z wykorzystaniem modelu DOM w PHP 4 .......................... 285 Odczyt dokumentów XML z wykorzystaniem modelu DOM w PHP 5 .......................... 287 Wykorzystanie modelu DOM do zapisywania dokumentów XML w PHP 4 ...................... 289 Wykorzystanie modelu DOM do zapisywania dokumentów XML w PHP 5 ...................... 291 Wykorzystanie rozszerzenia SimpleXML ................................ 292 Transformacje dokumentów XML z wykorzystaniem XSL w PHP 4 ......................................... 294 Transformacje dokumentów XML z wykorzystaniem XSL w PHP 5 ............................................. 295 Sprawdzanie poprawności dokumentów XML ...................... 296 8
  • 8. Spis treści 9 Komunikacja ze światem zewnętrznym ...........................299 Nawiązywanie połączenia z serwerami HTTP ........................299 Łączenie się z serwerami FTP ................................................303 Sprawdzanie, czy serwer odpowiada ....................................305 Tworzenie usług sieciowych z wykorzystaniem pakietu PEAR::XML-RPC ........................310 Korzystanie z usługi sieciowej za pomocą pakietu PEAR::XML-RPC ................................312 Tworzenie usługi sieciowej za pomocą klasy NuSOAP ...........314 Automatyczne generowanie kodu WSDL z wykorzystaniem klasy NuSOAP ........................................315 Wykorzystanie usługi sieciowej zaimplementowanej za pomocą klasy NuSOAP ..................................................319 Tworzenie usług sieciowych za pomocą pakietu PEAR::SOAP .........................................320 Automatyczne generowanie kodu WSDL dla usług sieciowych zaimplementowanych za pomocą pakietu PEAR::SOAP .........322 Wykorzystanie usługi sieciowej zaimplementowanej za pomocą pakietu PEAR::SOAP .........................................324 Tworzenie usług sieciowych z wykorzystaniem rozszerzenia SOAP w PHP 5 ...................325 Wykorzystanie usług sieciowych tworzonych za pomocą rozszerzenia SOAP w PHP 5 ..............................328 Skorowidz .........................................................................335 9
  • 9. 5 Zapamiętywanie Zapamiętywanieua ieuyo nó swńżt wikw t k ustawień użytkowników — pliki cookie i sesje HTTP (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 uzyskuje odpowiedź. Następnie połączenie jest zamykane. W konse- kwencji, jeśli następnym razem ten sam klient prześle żądanie do 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 problem dla aplikacji, które muszą utrzymywać stany (na przykład aplikacji e-commerce z implementacją koszyka na zakupy). Z ograniczeniem tym można jednak sobie poradzić na kilka sposobów. Podstawowa idea polega na przesłaniu pew- nych informacji wraz z odpowiedzią HTTP. Informacje te są przesyłane do serwera we wszystkich kolejnych żą- daniach. Istnieją następujące możliwości:
  • 10. Istota plików cookie ROZDZIAŁ 5 wysłanie danych za pomocą metody POST (tzn. za każ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). ZAPAMIĘTYWANIE USTAWIEŃ UŻYTKOWNIKÓW 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 cookie Pliki 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 blokowania w 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 1997 roku, w którym autor stwierdził, że każdy plik cookie moż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ło już takiego zainteresowania. Prawdą jest, że pliki cookie mają pewne ograniczenia: 160
  • 11. Istota plików cookie ROZDZIAŁ 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; maksymalnie 4096 bajtów (włącznie z nazwą pliku cookie i zna- kami = pomiędzy nazwami a wartościami), ZAPAMIĘTYWANIE USTAWIEŃ UŻYTKOWNIKÓW przeglądarki mogą zaakceptować tylko do 20 plików cookie 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óby stworzenia specjalnego dokumentu RFC dotyczącego plików cookie 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 tworzy się 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, domena i ścieżka dostępu do pliku cookie. Na przykład, jeśli od- wiedzimy witrynę http://www.php.net, witryna PHP prześle nagłówek w następującej postaci (oczywiście ustawienia języka i adres IP mogą być inne): Set-Cookie:COUNTRY=DEU%2C84.154.17.84; expires=Thu 19-May-05 15:23:29 GMT; path=/; domain=.php.net 161
  • 12. Istota plików cookie ROZDZIAŁ 5 Kiedy przeglądarka (lub użytkownik) zaakceptuje plik co- okie, zostanie on przesłany na serwer podany w nagłówku HTTP 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żej ZAPAMIĘTYWANIE USTAWIEŃ UŻYTKOWNIKÓW do tej daty. Jest to tzw. trwały plik cookie (ang. persistent cookie). 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 pliki cookie zostaną usunięte. Jeśli data ważności pliku cookie nie 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ądarka WWW. Podczas zamykania przeglądarki tymczasowe pliki cookie są usuwane. WSKAZÓWKA Aby oglądać nagłówki HTTP, można skorzystać ze specjalnych rozszerzeń standardowych przeglądarek WWW. W przypadku przeglądarek Mozilla (włącznie z przeglądarką Firefox) wielkie możliwości oferuje rozszerzenie LiveHTTPHeaders dostępne pod adresem http://livehttpheaders.mozdev.org/. Użytkownicy przeglą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. 162
  • 13. Tworzenie plików cookie ROZDZIAŁ 5 ZAPAMIĘTYWANIE USTAWIEŃ UŻYTKOWNIKÓW 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. 163
  • 14. Odczytywanie plików cookie ROZDZIAŁ 5 6. Informacja, czy plik cookie można przesyłać tylko za pomocą bezpiecznych połączeń HTTPS (SSL). W kodzie zamieszczonym na początku tego podrozdziału ustawiono prosty plik cookie sesji z wartością w postaci bieżącej wersji PHP. Na rysunku 5.2 pokazano okno z ostrzeżeniem wyświe- ZAPAMIĘTYWANIE USTAWIEŃ UŻYTKOWNIKÓW 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 pytanie do użytkownika o to, co z nim zrobić Odczytywanie plików cookie Wszystkie pliki cookie, do których serwer ma dostęp (nie muszą to być wszystkie pliki cookie, które są zapisane w przeglądarce!) są dostępne w tablicy superglobalnej 164
  • 15. Odczytywanie plików cookie ROZDZIAŁ 5 $_COOKIE. W kodzie zaprezentowanym poniżej wszystkie pliki cookie są odczytywane w pętli foreach i wysyłane do klienta w postaci tabeli HTML. <table> <?php foreach ($_COOKIE as $name => $value) { printf('<tr><td>%s</td><td>%s</td></tr>', htmlspecialchars($name), ZAPAMIĘTYWANIE USTAWIEŃ UŻYTKOWNIKÓW 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 przypadku uzyskamy 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łaniem zawartości HTML 165
  • 16. Pozbywanie się „magicznych” cudzysłowów z plików cookie ROZDZIAŁ 5 UWAGA Zazwyczaj interpreter PHP automatycznie unieszkodliwia znaki specjalne w wartościach plików cookie poprzez poprzedzenie ich znakami lewego ukośnika (szczególnie w przypadku przeka- zywania plików cookie poprzez URL). Jednak począwszy od PHP 5 można to robić ręcznie, poprzez wysłanie „surowych” danych pliku cookie. Aby to uczynić, należy przekazać do ZAPAMIĘTYWANIE USTAWIEŃ UŻYTKOWNIKÓW funkcji setrawcookie() te same parametry, które były przekazane 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ęcznie wywołać funkcję urlencode(). Pozbywanie się „magicznych” Pozbywanie się „magicznych” cudzysłowów z plików cookie cudzysłowów (apostrofów) z plików cookie Magiczne cudzysłowy (apostrofy), które opisano i wyklęto w poprzednim rozdziale, dotyczą również plików cookie, ponieważ to również są dane pochodzące od klientów. Tak wię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 zastosowano w poprzednim rozdziale do usunięcia ukośników z danych formularzy (danych GET i POST). 166
  • 17. Ustawianie daty ważności względem innej daty ROZDZIAŁ 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 { ZAPAMIĘTYWANIE USTAWIEŃ UŻYTKOWNIKÓW 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ści względem innej daty Data ważności pliku cookie jest przekazywana za pomocą trzeciego parametru funkcji setcookie(). Jest to liczba całkowita, dlatego trzeba użyć uniksowego znacznika czasu. 167
  • 18. Ustawianie daty ważności względem innej daty ROZDZIAŁ 5 W rozdziale 3., „Daty i godziny”, zamieszczono sporo informacji dotyczących sposobu wykorzystania tego ro- dzaju danych. <?php setcookie('version', phpversion(), time() + 21*24*60*60); ?> Próba wysłania pliku cookie. ZAPAMIĘTYWANIE USTAWIEŃ UŻYTKOWNIKÓW Ustawianie daty ważności pliku cookie względem innej daty (setcookie-expiry.php) Zwykle lepszym pomysłem jest ustawienie daty ważności pliku 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 regularnie modyfikować, ponieważ często data wygaśnięcia ważności nadchodzi bardzo szybko. Ustawianie czasu ważności na bardzo odległa datę w przyszłości, na przykład w roku 2030, uważa się za działanie nieprofesjonalne. Klient, który otrzyma taki plik cookie, najprawdopodobniej w roku 2030 już nie będzie się logował na serwerze. Z tych względów warto stosować daty względem innych dat. Funkcja PHP date() pobiera wartość uniksowego znacznika czasu dla daty bieżącej. Do tej wartości wy- starczy dodać liczbę sekund, przez jaką plik cookie ma być ważny. Kod zaprezentowany na poprzednim listingu ustawia plik cookie, który będzie ważny przez trzy ty- godnie. 168
  • 19. Ustawianie daty ważności specyficznej dla klienta ROZDZIAŁ 5 Ustawianie daty ważności specyficznej dla klienta setcookie('version', phpversion(), $_GET['time'] + 21*24*60*60) Należy pamiętać, że decyzja dotyczące tego, kiedy plik ZAPAMIĘTYWANIE USTAWIEŃ UŻYTKOWNIKÓW cookie traci ważność, jest podejmowana po stronie klienta i z wykorzystaniem ustawień daty i godziny klienta. Jeśli zatem data klienta jest ustawiona nieprawidłowo (czego po stronie serwera nie można kontrolować), pliki cookie będą traciły ważność wcześniej lub później niż się spodzie- wamy. Nie warto zatem ustawiać plików cookie, które bę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 listingu to działający po stronie klienta skrypt JavaScript, który sprawdza bieżącą godzinę wyrażoną jako uniksowy znacznik 169
  • 20. Usuwanie plików cookie ROZDZIAŁ 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 JavaScript polega na tym, że ta druga zwraca liczbę milisekund, jakie upłynęły od północy 1 stycznia 1970 roku, natomiast pierw- sza liczbę sekund. Z tego powodu wartość otrzymaną ze skryptu JavaScript należy najpierw podzielić przez 1000 ZAPAMIĘTYWANIE USTAWIEŃ UŻYTKOWNIKÓW i 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ści 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 plików cookie setcookie('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 operacja nie 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 170
  • 21. Usuwanie plików cookie ROZDZIAŁ 5 pliku cookie z datą ważności w przeszłości. Także w tym przypadku trzeba uwzględnić nieprawidłowe ustawienia czasu lokalnego, a zatem należy wybierać bardzo odległe daty utraty ważności, na przykład 10 lat wcześniej. Sposób ten zaimplementowano poniżej, gdzie usunięto plik cookie ustawiony w kodzie pokazanym na poprzednim listingu. W tej implementacji połączono obie metody — ustawiono ZAPAMIĘTYWANIE USTAWIEŃ UŻYTKOWNIKÓW wartość na pusty ciąg znaków i datę wygaśnięcia pliku cookie w przeszłości. Wynik działania skryptu pokazano na rysunku 5.4 — przeglądarka próbuje usunąć plik cookie poprzez ustawienie daty jego wygaśnięcia na określony czas (w przeszłości, a zatem plik cookie przestaje istnieć). Rysunek 5.4. Plik cookie będzie usunięty (jeśli użytkownik go zaakceptuje) <?php setcookie('version', '', time() - 10*365*24*60*60); ?> Próba usunięcia pliku cookie. Usuwanie plików cookie (deletecookie.php) 171
  • 22. Udostępnianie plików cookie dla wielu domen ROZDZIAŁ 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. Trzeba użyć argumentu o dodatniej wartości — na przykład 1. Udostępnianie plików cookie ZAPAMIĘTYWANIE USTAWIEŃ UŻYTKOWNIKÓW dla wielu domen setcookie('version', phpversion(), 0, '.przyklad.com'); Częścią nagłówka Set-Cookie wysyłanego przez serwer jest domena, która ma dostęp do tego pliku cookie. Jeśli wartość ta nie zostanie określona jawnie, domyślnie przyj- muje się domenę, z której wysłano plik cookie. Próba ustawienia 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.5 widać, że taką możliwość miały już stare przeglądarki Netscape 4.x). <?php setcookie('version', phpversion(), 0, '.przyklad.com'); ?> Próba przesłania pliku cookie. Ustawianie domeny dla pliku cookie (setcookie-domain.php) 172
  • 23. Udostępnianie plików cookie dla wielu domen ROZDZIAŁ 5 ZAPAMIĘTYWANIE USTAWIEŃ UŻYTKOWNIKÓW Rysunek 5.5. Nawet w przeglądarce Netscape 4.x można zablokować 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.com i ssl.przyklad.com. Sytuacja dotyczy dużych witryn WWW z 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ą 173
  • 24. Sprawdzanie, czy klient obsługuje pliki cookie ROZDZIAŁ 5 miały dostęp wszystkie domeny trzeciego poziomu domeny przyklad.com. Jest jednak jedno „ale”. Strony umieszczone w domenie http://przyklad.com nie będą miały dostępu do tego 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. ZAPAMIĘTYWANIE USTAWIEŃ UŻYTKOWNIKÓW Sprawdzanie, czy klient obsł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 odpowiedzi HTTP. W następnym żądaniu, jeśli użytkownik zaak- ceptuje plik cookie, klient przesyła go z powrotem na serwer. Z tego powodu wywołanie funkcji setcookie() i późniejsze sprawdzenie zawartości tablicy $_COOKIE nie zadział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); 174
  • 25. Sprawdzanie, czy klient obsługuje pliki cookie ROZDZIAŁ 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: ' . ZAPAMIĘTYWANIE USTAWIEŃ UŻYTKOWNIKÓW 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, czy operacja zakończyła się sukcesem. W zaprezentowanym powyżej kodzie ustawiono dwa pliki cookie — jeden tymczasowy i drugi trwały — ponieważ niektóre przeglądarki można tak skonfigurować, że jeden typ 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ą funkcji header() oraz nagłówka HTTP Location. Oczywiście trzeba tak skonfigurować przeglądarkę, aby w momencie przesłania pliku cookie był wyświetlany ko- munikat — znacznie ułatwia to debugowanie. 175
  • 26. Zapisywanie wielu danych w jednym pliku cookie ROZDZIAŁ 5 Zapisywanie wielu danych w jednym pliku cookie setcookie('cookiedata', serialize($cookiedata) Zazwyczaj w pliku cookie jest ustawiona jedna wartość ZAPAMIĘTYWANIE USTAWIEŃ UŻYTKOWNIKÓW — ciąg znaków. Z tego powodu, aby zapisać za pomocą plików cookie wiele danych, trzeba użyć wielu plików cookie. Takie działanie stwarza jednak pewne problemy — na przykład z powodu ograniczenia 20 plików cookie na domenę. Z tego względu w niektórych przypadkach ma sens zapisywanie wielu danych w jednym pliku cookie. Do tego przydają się tablice. Wartościami plików cookie mogą być jednak wyłącznie ciągi znaków. Z tego powodu tablicę trzeba przekształcić na ciąg znaków za pomocą funkcji serialize(). Później moż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), 176
  • 27. Zapisywanie wielu danych w jednym pliku cookie ROZDZIAŁ 5 time() + 30*24*60*60); } function getAllCookieData() { if (isset($_COOKIE['cookiedata'])) { $formdata = $_COOKIE['cookiedata']; if ($formdata != '') { return unserialize($formdata); } else { return array(); ZAPAMIĘTYWANIE USTAWIEŃ UŻYTKOWNIKÓW } } 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 plik cookie 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. 177
  • 28. Zapisywanie ustawień językowych użytkownika ROZDZIAŁ 5 Z kolei na listingu zamieszczonym poniżej wykorzystano zdefiniowaną bibliotekę do zaimplementowania testu dla plików cookie znanych z poprzedniego podrozdziału. <?php require_once 'getCookieData.inc.php'; if (isset($_GET['step']) && $_GET['step'] == '2') { ZAPAMIĘTYWANIE USTAWIEŃ UŻYTKOWNIKÓW $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żytkownika setcookie('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, na przykł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, 178
  • 29. Zapisywanie ustawień językowych użytkownika ROZDZIAŁ 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- ZAPAMIĘTYWANIE USTAWIEŃ UŻYTKOWNIKÓW 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.php napisany w określonej wersji językowej. W tym pliku prze- chowywany jest kod z listingu zamieszczonego na początku tego podrozdziału. Instrukcja sprawdza, czy już ustawiono plik cookie dla wersji językowej, a jeśli nie — ustawia plik cookie dla bieżącego katalogu (odczytanego za pomocą odwołania do elementu $_SERVER['PHP_SELF']). 179
  • 30. Zapisywanie ustawień językowych użytkownika ROZDZIAŁ 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) ZAPAMIĘTYWANIE USTAWIEŃ UŻYTKOWNIKÓW UWAGA Jest bardzo istotne, aby ustawić ścieżkę pliku cookie na główny katalog serwera WWW. W innym przypadku warto- ścią domyślną ścieżki będzie katalog bieżący i plik będzie mó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ć, czy ustawiono 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 trzeba wprowadzić następujący kod: <?php if (isset($_COOKIE['lang']) && $_COOKIE['lang'] != '') { header("Location: {$_COOKIE['lang']}"); } ?> 180
  • 31. Sesje ROZDZIAŁ 5 Sesje Sesja to nic innego jak wizyta użytkownika na stronie WWW. Użytkownik klika jakieś łącza, przegląda niektóre strony i wychodzi. Działania użytkownika w witrynie WWW definiują sesję. Jeśli użytkownik nie zażąda danych z witryny WWW przez pewien czas, na przykład 20 mi- ZAPAMIĘTYWANIE USTAWIEŃ UŻYTKOWNIKÓW nut, sesja kończy się. Protokół HTTP nie zawiera żadnego mechanizmu obsługi sesji, ponieważ jest bezstanowy. PHP zawiera jednak wbu- dowaną obsługę sesji, dzięki czemu skorzystanie z nich jest stosunkowo proste. Po utworzeniu sesji PHP generuje jej identyfikator w posta- ci długiego ciągu znaków. Następnie tworzy zapis w pliku lub bazie danych dotyczący określonej sesji. Po wykonaniu tych 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ć przekazywany pomię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ą niepotrzebnie przesyłane istotne dane. Konfiguracja mechanizmu sesji języka PHP jest w całości zapisana w sekcji [session] pliku konfiguracyjnego php.ini. Domyślne ustawienia nie pasują do wszystkich zastoso- wań, dlatego w kolejnych podrozdziałach opisano kilka możliwych konfiguracji. 181
  • 32. Gdzie należy zapisywać sesje? ROZDZIAŁ 5 Gdzie należy zapisywać sesje? Zazwyczaj dane sesji są zapisywane w plikach. Lokalizację tych plików ustawia się za pomocą dyrektywy pliku php.ini session.save_path. Oczywiście katalog ustawiony za po- mocą tej dyrektywy musi po pierwsze istnieć, a po drugie proces PHP (zwykle proces serwera WWW) musi mieć ZAPAMIĘTYWANIE USTAWIEŃ UŻYTKOWNIKÓW 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 za tym idzie dużej liczby sesji, interpreter PHP nie powinien umieszczać 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 danych sesji 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. Aby mechanizm sesji PHP mógł zapisywać dane w podkata- logach, trzeba je wcześniej utworzyć. Do tego celu służy skrypt mod_files.sh w katalogu ext/sessions. Oczywiście prawo do odczytywania tego katalogu powi- nien posiadać tylko serwer WWW. W innym przypadku inni użytkownicy systemu mogliby odczytywać informa- cje o sesji potencjalnie zawierające wrażliwe dane. 182
  • 33. W jaki sposób zachować stan sesji? ROZDZIAŁ 5 W jaki sposób zachować stan sesji? Identyfikator sesji musi być przesłany do przeglądarki w każdej odpowiedzi, a co ważniejsze — musi być prze- słany z powrotem na serwer wraz z każdym żądaniem. ZAPAMIĘTYWANIE USTAWIEŃ UŻYTKOWNIKÓW Najprościej można zaimplementować ten mechanizm za pomocą plików cookie. PHP przesyła do klienta plik cookie o 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ć pewne zagrożenie (na przykład modyfikowanie sesji — ang. session fixation, lub przechwytywanie sesji — ang. session hijac- king), ale jest dość praktyczne. Wykorzystują je wszyst- kie znane witryny e-commerce, na przykład Amazon. Jeśli odwiedzimy ich witrynę WWW i załadujemy stronę, iden- tyfikator sesji zostanie automatycznie dołączony na końcu adresu URL. 183
  • 34. Aktywacja sesji ROZDZIAŁ 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 automatycznie włączona dla binarnych dystrybucji przeznaczonych dla systemów Windows i Mac OS X. Można również zezwolić na przekazywanie w adresach ZAPAMIĘTYWANIE USTAWIEŃ UŻYTKOWNIKÓW URL tylko plików cookie, bez identyfikatorów sesji. Do tego 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ć je w 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) trzeba jednak wziąć pod uwagę, że niektórzy odwiedzający (poten- cjalni klienci!) nie włączą obsługi plików cookie. W takim przypadku sesje gwarantują wygodny sposób pokonania tego ograniczenia. Aktywacja sesji session_start() Korzystanie z mechanizmów zarządzania sesjami zawsze wymaga zasobów, a w związku z tym wiąże się z obniże- niem wydajności. Dlatego właśnie sesje trzeba aktywować. 184
  • 35. Czytanie i zapisywanie sesji ROZDZIAŁ 5 Ponieważ operacja ta może wymagać przesłania plików cookie, 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 pliku php.ini session.auto_start = 1, aktywacja sesji na poziomie skryptu, za pomocą funkcji ZAPAMIĘTYWANIE USTAWIEŃ UŻYTKOWNIKÓW session_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ż dane są zapisane po stronie serwera, można zapisać dane sesji i odczytać je już w następnej instrukcji PHP bez konieczno- ści transmisji, tak jak to było w przypadku plików cookie. 185
  • 36. Zamykanie sesji ROZDZIAŁ 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. ZAPAMIĘTYWANIE USTAWIEŃ UŻYTKOWNIKÓW Rysunek 5.6. Zawartość pliku sesji utworzonego przez kod pokazany na poprzednim listingu Zamykanie sesji session_destroy() W niektórych przypadkach, na przykład kiedy użytkownik się wyloguje, wszystkie dane sesji należy usunąć, a sesję za- mknąć. Oczywiście można przetworzyć tablicę $_SESSION w pętli foreach i ustawić każdą z wartości na pusty ciąg znaków, ale istnieje szybszy sposób — wystarczy wywołać funkcję session_destroy(). Po wykonaniu tej funkcji, tak jak wskazuje nazwa (destroy — niszczyć), wszystkie dane w bieżącej sesji zostaną zniszczone. <?php session_start(); echo 'Przed: <pre>'; print_r($_SESSION); echo '</pre>Po: <pre> '; session_destroy(); 186
  • 37. Modyfikacje identyfikatora sesji ROZDZIAŁ 5 print_r($_SESSION); echo '</pre>'; ?> Usuwanie wszystkich danych sesji (session_destroy.php) Modyfikacje ZAPAMIĘTYWANIE USTAWIEŃ UŻYTKOWNIKÓW identyfikatora sesji session_regenerate_id() Jednym ze znanych ataków przeciwko witrynom WWW zabezpieczonych za pomocą sesji jest przechwycenie iden- tyfikatora sesji użytkownika (na przykład w wyniku analizy zapisów HTTP_REFERER w żądaniach HTTP), a następnie wykorzystanie 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 gdy użytkownik się zaloguje. Przykładowo w witrynie Amazon użytkownicy, którzy zostali wcześniej uwierzytelnieni za pomocą 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) 187
  • 38. Tworzenie dynamicznych łączy z obsługą sesji ROZDZIAŁ 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 zamieszczonym wcześniej kodzie, gdzie za pomocą funkcji session_id() odczytano stary i bieżący identyfikator sesji. Przykładowy wynik działania tego skryptu pokazano na rysunku 5.7. ZAPAMIĘTYWANIE USTAWIEŃ UŻYTKOWNIKÓW 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 łączy z obsługą sesji $name = urlencode(session_name()); $id = urlencode(session_id()); echo "<a href="page.php?$name=$id">dynamiczne łącze</a>"; 188
  • 39. Tworzenie dynamicznych łączy z obsługą sesji ROZDZIAŁ 5 Zastosowanie ustawienia session.use_trans_sid w celu automatycznej aktualizacji wszystkich łączy w taki sposób, by zawierały identyfikatory sesji, to dobry pomysł, jednak sposó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, ZAPAMIĘTYWANIE USTAWIEŃ UŻYTKOWNIKÓW session_id() — zwraca bieżący identyfikator sesji. Tak więc kod zamieszczony na początku tego podrozdziału tworzy dynamiczne łącze zawierające informacje o sesji. W ten sposób programista może tworzyć dynamiczne łącza z obsługą sesji. Oto przykładowy wynik działania zamieszczonego wyżej kodu: <a href="page.php?PHPSESSID=2600b43e0fecb 4d5a990bf848289a8fe">dynamiczne łącze</a> WSKAZÓWKA Kiedy korzystamy z formularzy HTML, PHP automatycznie dołą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" />"; ?> 189
  • 40. Implementacja własnego mechanizmu zarządzania sesjami ROZDZIAŁ 5 Implementacja własnego mechanizmu zarządzania sesjami session_set_save_handler( 'sess_open', 'sess_close', 'sess_read', ZAPAMIĘTYWANIE USTAWIEŃ UŻYTKOWNIKÓW '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 sesji w 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 konsekwentnie stosować 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 tym podrozdziale 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 baz danych w PHP można znaleźć w rozdziale 7.). 190
  • 41. Implementacja własnego mechanizmu zarządzania sesjami ROZDZIAŁ 5 Funkcję PHP session_set_save_handler() można wy- korzystać do zdefiniowania własnych funkcji dla sześciu operacji wewnętrznie wykonywanych przez PHP: otwierania sesji, zamykania sesji, odczytywania zmiennej sesji, ZAPAMIĘTYWANIE USTAWIEŃ UŻYTKOWNIKÓW zapisywania zmiennej sesji, niszczenia sesji, porządkowania (tzw. odśmiecania — ang. garbage collection — polegającego, na przykład, na usuwaniu starych danych sesji z bazy danych). Kod dla wszystkich tych sześciu operacji, który odczytuje i 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ższym listingu za pomocą funkcji require_once. Po wykonaniu tych operacji można wykorzystywać sesje w standardowy sposó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() { 191
  • 42. Implementacja własnego mechanizmu zarządzania sesjami ROZDZIAŁ 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() { ZAPAMIĘTYWANIE USTAWIEŃ UŻYTKOWNIKÓW 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
  • 43. Implementacja własnego mechanizmu zarządzania sesjami ROZDZIAŁ 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)) ZAPAMIĘTYWANIE USTAWIEŃ UŻYTKOWNIKÓW ); 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); 193
  • 44. Tworzenie zabezpieczonego obszaru z wykorzystaniem sesji ROZDZIAŁ 5 mysqli_query( $GLOBALS['sess_mysqli'], sprintf('DELETE FROM sessiondata WHERE access < '%s'', $timestamp) ); } session_set_save_handler( 'sess_open', 'sess_close', 'sess_read', ZAPAMIĘTYWANIE USTAWIEŃ UŻYTKOWNIKÓW '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 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
  • 45. Tworzenie zabezpieczonego obszaru z wykorzystaniem sesji ROZDZIAŁ 5 ZAPAMIĘTYWANIE USTAWIEŃ UŻYTKOWNIKÓW Rysunek 5.8. Dane sesji są teraz zapisane w bazie danych Sesje to doskonały sposób zabezpieczenia wydzielonych częś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 stronach wystarczy sprawdzić, czy zdefiniowano tę zmienną. Najpierw sprawdzimy, czy zdefiniowano zmienną sesji. Kod zamieszczony na początku tego podrozdziału należy włą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śniej kod, 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 195
  • 46. Tworzenie zabezpieczonego obszaru z wykorzystaniem sesji ROZDZIAŁ 5 ZAPAMIĘTYWANIE USTAWIEŃ UŻYTKOWNIKÓW Rysunek 5.9. Formularz logowania — zwróćmy uwagę na stronę wymienioną w adresie URL hasła). Jak można zobaczyć, adres URL jest podany jako parametr GET, a zatem, jeśli go zdefiniowano, kod skryptu logowania przekieruje użytkownika do strony, z której wysł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 zamieszczony na dwóch poprzednich listingach. 196
  • 47. 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' Jeśli wykorzystanie uwierzytelniania z mechanizmem za- ZAPAMIĘTYWANIE USTAWIEŃ UŻYTKOWNIKÓW 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órych plików lub katalogów. Na przykład użytkownicy serwera Apache mogą wykorzystać pliki .htaccess. Pod adresem http://apache-server.com/tutorials/ATusing-htaccess.html można znaleźć sporo informacji na ten temat. Serwer Microsoft IIS jest wyposażony w narzędzie z graficznym interfejsem użytkownika do definiowania praw dostępu, a zatem również dla tego serwera można zdefiniować podobny mechanizm. <?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 { ?> 197
  • 48. Tworzenie zabezpieczonego obszaru bez korzystania z sesji ROZDZIAŁ 5 <!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) ZAPAMIĘTYWANIE USTAWIEŃ UŻYTKOWNIKÓW Jednym z rozwiązań, które w dużym stopniu jest niezależne od platformy, jest wykorzystanie uwierzytelniania HTTP. W przypadku przesłania kodu statusu HTTP 401 (nie- uprawniony użytkownik) przeglądarka wyświetli pytanie o nazwę użytkownika i hasło. Informacje te są później dostępne w elementach tablicy superglobalnej $_SERVER- ['PHP_AUTH_USER'] oraz $_SERVER['PHP_AUTH_PW'], ale jedynie wtedy, gdy PHP działa jako moduł serwera. Nie są 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ższym listingu. Okno dialogowe z pytaniem o nazwę użytkow- nika i hasło pokazano na rysunku 5.10. 198
  • 49. Tworzenie zabezpieczonego obszaru bez korzystania z sesji ROZDZIAŁ 5 ZAPAMIĘTYWANIE USTAWIEŃ UŻYTKOWNIKÓW 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 zabezpieczania stron PHP, pakiet HTTP_Session bazuje na mechanizmie obsługi sesji języka PHP, ale oferuje obiektowy dostęp do infor- macji dotyczących sesji. 199