Podręcznik PHP
Poprzedni |  | Następny

# XCVI. Sesje

Obsługa sesji w PHP ma na celu zapewnienie sposobu na zachowanie pewnych danych w trakcie następujących po sobie wywołań strony. Pozwala to na budowanie bardziej spersonalizowanych aplikacji i zwiększenie atrakcyjności twojej strony internetowej.

Jeśli jesteś zaznajomiony z zarządzaniem sesją w PHPLIB, zauważysz że pewnie koncepcje są podobne w obsłudze sesji PHP.

Gość wchodzący na twoją stronę WWW otrzymuje unikalny identyfikator, tzw. id sesji. Jest ono przechowywane albo jako ciasteczko po stronie użytkownika lub propagowane w URL'u.

Obsługa sesji pozwala ci na rejestrowanie dowolnej ilości zmiennych, które mają być przekazywane pomiędzy stronami. Kiedy gość wchodzi na twoją strone, PHP automatycznie sprawdzi (jeśli session.auto_start jest ustawione na 1) lub na twoje życzenie (jawnie przez wywołanie session_start() lub niejawnie przez wywołanie session_register()) czy specyficzne id sesji zostało przypisane. Jeśli tak, poprzednio zachowane środowisko jest odtwarzane.

Wszystkie zarejestrowane zmienne są serializowane po wykonaniu całego kodu strony. Zarejestrowane zmienne, które są niezdefiniowane, są zaznaczane jako niezdefiniowane. Nie są one definiowane przez moduł sesji w następujących po sobie wywołaniach, chyba że użytkownik zdefiniuje je później.

Opcje konfiguracyjne `track_vars` i `register_globals` wpływają na to, jak zmienne sesyjne są przechowywane i odtwarzane.

> Notatka: Od PHP w wersji 4.0.3 opcja `track_vars` jest zawsze włączona.

> Notatka: Od wersji PHP 4.1.0 dostępna jest globalna zmienna `$_SESSION`, podobnie jak `$_POST`, `$_GET`, `$_REQUEST` i tak dalej. W odróżnieniu od `$HTTP_SESSION_VARS`, `$_SESSION` jest zawsze globalna. W związku z tym `global` nie powinno być użyte do `$_SESSION`.

Jeśli włączona jest opcja `track_vars` a `register_globals` jest wyłączona, tylko pozycje należące do zmiennej asocjacyjnej `$HTTP_SESSION_VARS` mogą być zarejestrowane jako zmienne sesyjne. Odtworzone zmienne sesyjne będą dostępne tylko w zmiennej `$HTTP_SESSION_VARS`.

Przykład 1. Rejestracja zmiennej z włączoną opcją `track_vars`
`<?php session_start(); if (isset($HTTP_SESSION_VARS['count'])) { $HTTP_SESSION_VARS['count']++; } else { $HTTP_SESSION_VARS['count'] = 0; } ?>`

Użycie `$_SESSION` (lub `$HTTP_SESSION_VARS` dla wersji PHP 4.0.6 i starszych) jest wskazane ze względów bezpieczeństwa i czytelności kodu. Używając `$_SESSION` lub `$HTTP_SESSION_VARS` nie ma potrzeby używać funkcji session_register()/session_unregister()/session_is_registered(). Użytkownicy mogą uzyskiwać dostęp do zmiennych sesyjnych tak jak do normalnych zmiennych.

Przykład 2. Rejestrowanie zmiennych przez $_SESSION
`<?php session_start(); // Użyj $HTTP_SESSION_VARS dla PHP 4.0.6 i starszych if (!isset($_SESSION['count'])) { $_SESSION['count'] = 0; } else { $_SESSION['count']++; } ?>`

Przykład 3. Wyrejestrowywanie zmiennej korzystając z $_SESSION
`<?php session_start() // Użyj $HTTP_SESSION_VARS dla PHP 4.0.6 i starszych unset($_SESSION['count']); ?>`

Jeśli włączona jest opcja `register_globals`, wszystkie globalne zmienne mogą być zarejestrowane jako zmienne sesyjne a zmienne sesyjne będą odtworzone do odpowiadających im zmiennych globalnych. Ponieważ PHP musi wiedzieć które globalne zmienne są zarejestrowane jako zmienne sesyjne, użytkownik musi użyć funkcji session_register() podczas gdy `$HTTP_SESSION_VARS`/`$_SESSION` nie muszą używać session_register().

Uwaga!
Jeśli używane są tablice `$HTTP_SESSION_VARS`/`$_SESSION` i i wyłączona jest opcja `register_globals`, nie powinno się używać session_register(), session_is_registered() i session_unregister(). Jeśli włączona zostanie opcja `register_globals`, powinno się używać session_unregister() ponieważ zmienne sesyjne są rejestrowane jako zmienne globalne kiedy dane sesyjne są deserializowane. Wyłączenie `register_globals` jest zalecane ze względów bezpieczeństwa i wydajności.

Przykład 4. Rejestracja zmiennych z włączoną opcją `register_globals`
`<?php if (!session_is_registered('count')) { session_register('count'); $count = 0; } else { $count++; } ?>`

Jeśli włączone są obie opcje, `track_vars` i `register_globals`, globalne zmienne i wpisy w `$HTTP_SESSION_VARS`/`$_SESSION` będą referencjami do tej samej, już zarejestrowanej zmiennej.

Jeśli użytkownik użyje session_register() do zarejestrowania zmiennej sesyjnej, `$HTTP_SESSION_VARS`/`$_SESSION` nie będą zawierały tych zmiennych w tablicy dopóki nie zostanie ona odczytana z miejsca przechowywania sesji (np. do czasu następnego wywołania).

Istnieją dwie metody propagacji identyfikatora sesji:

- Ciasteczka

- Parametry URL'a

Moduł sesji obsługuje obie metody. Ciasteczka są metodą optymalną, ale ponieważ nie są one pewne (klienci nie muszą ich akceptować), nie możemy na nich polegać. Druga metora wstawia identyfikatory sesji bezpośrednio do URL'i.

PHP może to robić 'przezroczyście' jeśli został skompilowany z opcją `--enable-trans-sid`. Jeśli włączysz tą opcję, względne URI zostaną automatycznie podmienione tak, aby zawierały identyfikator sesji. Możesz także użyć stałej `SID` która jest definiowana jeśli klient nie wysłał odpowiedniego ciastka. `SID` jest albo w postaci `nazwa_sesji=id_sesji` lub pustym stringiem.

> Notatka: Dyrektywa arg_separator.output którą można umieścić w pliku konfiguracyjnym `php.ini` pozwala ustawić własny separator argumentów.

Poniższy przykład demonstruje jak zarejestrować zmienną i jak prawidłowo wstawić link do kolejnej strony korzystając ze stałej SID.

Przykład 5. Zliczanie ilości odwiedzin pojedyńczego użytkownika
`<?php if (!session_is_registered('count')) { session_register('count'); $count = 1; } else { $count++; } ?> Witaj gościu. Oglądasz tą stronę <?php echo $count; ?> raz.<p> <?php # <?php echo SID?> (<?=SID?> może być użyte jeśli włączona jest możliwość # używania krótkich tagów) jest konieczne do zachowania identyfikatora # sesji jeśli użytkownik wyłączył ciastka ?> Aby kontynuować, <A HREF="nextpage.php?<?php echo SID?>">kliknij tutaj</A>`

`<?=SID?>` nie jest konieczne jeśli przy kompilacji PHP użyta została opcja `--enable-trans-sid`.

> Notatka: PHP zakłada, że bezwzględne URLe odnoszą się do zewnętrznych serwisów, więc nie trzeba przekazywać SID, ponieważ istniałoby niebezpieczeństwo podkradania SIDów przez inny serwer.

Aby zaimplementować przechowywanie danych sesyjnych w bazie danych lub w dowolnej innej postaci, musisz użyć session_set_save_handler() do stworzenia zestawu funkcji przechowujących dane.

System zarządzania sesją obsługuje wiele opcji konfiguracyjnych, które możesz wstawić do swojego pliku `php.ini`. Oto ich krótki przegląd.

- `session.save_handler` definiuje nazwę procedury obsługi, która jest używana do przechowywania i odczytu danych skojarzonych z sesją. Domyślnie `files`.

- `session.save_path` definiuje argument, który jest przekazywany procedurze obsługi zapisu danych. Jeśli wybierzesz domyślną procedurę obsługi, jest to ścieżka gdzie tworzone będą pliki z danymi. Domyślnie `/tmp`. Jeśli głębokość ścieżki określonej w parametrze `session.save_path` jest większa niż 2, nie przeprowadzone zostanie zbieranie śmieci.

  Ostrzeżenie
  Jeśli w tej opcji ustawisz katalog, który jest ogólnie dostępny, jak na przykład `/tmp` (domyślna wartość), inni użytkownicy serwera będą w stanie przechwycić sesję przez pobranie listy plików z tego katalogu.

- `session.name` określa nazwę sesji, która jest używana jako nazwa ciastka. Powinna zawierać tylko znaki alfanumeryczne. Domyślnie `PHPSESSID`.

- `session.auto_start` określa, czy moduł sesji rozpoczyna sesję na początku wywołania. Domyślnie `0` (wyłączony).

- `session.cookie_lifetime` określa długość życia w sekundach ciastka przesyłanego do przeglądarki. Wartość 0 oznacza "dopóki przeglądarka nie została zamknięta". Domyślnie `0`.

- `session.serialize_handler` określa nazwę procedury obsługi, która zostanie użyta do serializacji/odserializacji danych. Obecnie obsługiwany jest wewnętrzny format PHP (nazwa `php` i WDDX (nazwa `wddx`). WDDX jest jedynym dostępnym formatem jeśli PHP zostało skompilowane z obsługą WDDX. Domyślnie `php`.

- `session.gc_probability` określa prawdopodobieństwo w procentach rozpoczęcia procedury gc (garbage collection - zbieranie śmieci) przy każdym wywołaniu. Domyślnie `1`.

- `session.gc_maxlifetime` określa ilość sekund, po jakich dane będą rozpoznawane jako 'śmieci' i usuwane.

- `session.referer_check` zawiera podciąg, z którym HTTP_REFERER ma być sprawdzany. Jeśli HTTP_REFERER został wysłany przez klienta i nie zawierał podanego podciągu, identyfikator sesji podany przez takiego klienta zostanie uznany za nieważny. Domyślnie jest to ciąg pusty.

- `session.entropy_file` podaje ścieżkę do zewnętrznego zasobu (pliku), który będzie użyty jako dodatkowe źródło entropii w procesie tworzenia identyfikatora sesji. Przykłady to `/dev/random` lub `/dev/urandom`, które są dostępne na wielu systemach Unix.

- `session.entropy_length` określa liczbę bajtów, która będzie odczytana z pliku podanego powyżej. Domyślnie `0` (wyłączona).

- `session.use_cookies` określa czy moduł będzie używał ciasteczek do przechowywania identyfikatora sesji po stronie klienta. Domyślnie `1` (włączona).

- `session.use_only_cookies` określa czy moduł będzie używał tylko ciasteczek do przechowywania identyfikatora sesji po stronie klienta. Domyślna wartość to `0` (dla wstecznej kompatybilności). Włączenie tej opcji zapobiega atakom opartym o przekazywanie identyfikatora sesji przez URL. Ta opcja została dodana w `PHP` 4.3.0.

- `session.cookie_path` określa ścieżkę która będzie podana w session_cookie. Domyślnie `/`.

- `session.cookie_domain` określa domenę która ma być podana w session_cookie. Domyślnie - pusta.

- `session.cache_limiter` określa metodę używaną do przechowywania stron sesyjnych w pamięci podręcznej (nocache/private/private_no_expire/public). Domyślnie `nocache`.

- `session.cache_expire` określa czas życia w minutach stron sesyjnych zachowanych w pamięci podręcznej. Nie ma to efektu dla metody `nocache`. Domyślnie `180`

- `session.use_trans_sid` określa czy będzie używana obsługa przezroczystego przekazywania identyfikatora sesji. Opcja brana pod uwagę tylko jeśli PHP zostało skompilowane z opcją `--enable-trans-sid`. Domyślnie `1` (włączona).

- `url_rewriter.tags` określa które tagi HTML zostają przepisane w celu dopisania identyfikatora sesji jeśli włączona została opcja przezroczystego przekazywania identyfikatora sesji. Domyślnie `a=href,area=href,frame=src,input=src,form=fakeentry`

> Notatka: Obsługa sesji została dodana w PHP 4.0.

Poprzedni | Spis treści | Następny
sesam_settransaction | Początek rozdziału | session_cache_expire