Gratulacje, kretor Mój egrafik został zakończony. Jeżeli rejestrowałeś się w tym kreatorze, pamiętaj aby kliknąć w link potwierdzający, wysłany na Twój adres email. Jeżeli tego nie zrobisz, nie będziesz mógł się zalogować, a dodane przez Ciebie wpisy nie zostaną opublikowane.
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.
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.
Uwaga!
Po włączeniu dyrektywy
session.auto_start nie
jest możliwe dodawanie obiektów do sesji. Dzieje się tak, ponieważ
definicje klas muszą być załadowane przed rozpoczęciem sesji aby
możliwe było odtworzenie obiektów zawartych w sesji.
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.
Ostrzeżenie
Niektóre typy danych nie mogą być serializowane, a w związku z tym
przechowywane w sesjach. Do typów takich należą zasoby
(resource) lub obiekty z zapętlonymi referencjami (np.
obiekty, które przekazują referencje do siebie do innego obiektu).
Notatka:
Obsługa sesji została dodana w PHP 4.0.
Notatka:
Należy zauważyć, że zapis sesji nie jest tworzony dopóki nie zostanie w
niej zarejestrowana zmienna poprzez funkcję
session_register() lub przez dodanie klucza do tablicy
superglobalnej $_SESSION
. Dzieje się tak nawet pomimo
faktu rozpoczęcia sesji poprzez wywołanie funkcji
session_start().
Moduł sesji nie może zagwarantować, że informacje, które są przechowywane
w sesji, mogą być przeglądane tylko przez użytkownika, który stworzył tą
sesję. Niezbędne jest przedsięwzięcie dodatkowych działań aby ochronić
spójność sesji, zależnie od wartości do niej przypisanych.
Należy ocenić wartość danych przechowywanych w sesjach i zastosować
dodatkowe zabezpieczenia - działania takie są zazwyczaj powiązane ze
zmniejszeniem wygody użytkowników. Na przykład, aby ochronić użytkowników
przed prostymi sposobami social engineering, należy włączyć dyrektywę
session.use_only_cookies
. W takim przypadku użytkownik
musi mieć w swojej przeglądarce włączone ciasteczka - inaczej sesje nie
będą działać.
Istnieje kilka dróg, przez które istniejący identyfikator sesji może
zostać przejęty przez osoby trzecie. Przejęty identyfikator sesji pozwala
osobom trzecim uzyskać dostęp do wszystkich zasobów powiązanych z daną
sesją. Po pierwsze, identyfikator może być przejęty poprzez URLe
zawierające identyfikatory sesji. Jeśli serwis zawiera linki do stron
zewnętrznych, URL zawierający identyfikator sesji może być zapisany w
logach odnośników (referrer) tego zewnętrznego serwisu. Po drugie,
bardziej aktywny napastnik może podsłuchać ruch sieciowy. Jeśli nie jest
on zaszyfrowany, identyfikatory będą przesyłane przez sieć czystym
tekstem. Rozwiązaniem tego problemu jest zaimplementowanie szyfrowania
SSL i uczynienie go obowiązkowym dla wszystkich użytkowników.
Do zbudowania tego rozszerzenia nie są wymagane
żadne zewnętrzne biblioteki.
Notatka:
Opcjonalnie możliwe jest używanie do przechowywania sesji pamięci
współdzielonej (mm), co zostało zaimplementowane przez Ralfa S.
Engelschalla. Należy pobrać rozszerzenie
mm i zainstalować je. Opcja ta nie jest
dostępna na platformy Windows. Moduł przechowywania sesji mm nie
gwarantuje jednak, że równoczesny dostęp do tej samej sesji jest
właściwie blokowany. Bardziej poprawne może być zastosowanie systemów
plików opartych o pamięć współdzieloną (takich jak tmpfs w systemach
Solaris/Linux lub /dev/md na BSD) do przechowywania plików sesji,
poniważ są one prawidłowo blokowane. Dane sesji są przechowywane w
pamięci, a więc restart serwera HTTP powoduje ich usunięcie.
Obsługa sesji jest domyślnie włączona. Aby zbudować PHP bez obsługi sesji,
należy podać opcję --disable-session
do
wywołania configure. Aby użyć pamięci współdzielonej do przechowywania
sesji, należy podać opcję --with-mm[=DIR]
.
PHP
w wersji dla systemów
Windows posiada wbudowaną obsługę dla tego rozszerzenia. Nie trzeba ładować
żadnych dodatkowych rozszerzeń aby korzystać z tych funkcji.
Notatka:
Domyślnie, wszystkie dane związane z poszczególnymi sesjami będą
przechowywane w plikach w katalogu określonym przez opcję
session.save_path. Plik dla każdej sesji (niezależnie od tego, czy do sesji
przypisane są jakiekolwiek dane) zostanie stworzony. Wiąże się to z faktem,
że sesja jest otwierana (plik jest tworzony) ale nie są zapisywane żadne
dane. To zachowanie ma efekt uboczny poprzez ograniczenia systemu plików i
możliwe jest, że inny system obsługi sesji (na przykład taki, który używa
bazy danych) nie śledzi sesji, które nie zawierają danych.
session.save_handler
określa nazwę systemu obsługi,
który będzie odpowiedzialny za przechowywanie i odzyskiwanie danych
przypisanych do sesji. Domślna wartość to
files
. Patrz także:
session_set_save_handler().
session.save_path
określa argument, który przekazywany
jest do systemu zapisywania sesji. Jeśli ustawiony jest domślny system,
plikowy, ta ścieżka będzie określała gdzie tworzone będą pliki. Domyślna
wartość to /tmp
. Patrz także:
session_save_path().
Opcjonalny argument N do tej dyrektywy określa liczbę poziomów katalogów
w których będą przechowywane pliki z sesjami.
Na przykład ustawienie '5;/tmp'
może prowadzić do
stworzenia pliku z sesją o ścieżce
/tmp/4/b/1/e/3/sess_4b1e384ad74619bd212e236e52a5a174If
. Aby używać N należy stworzyć wszystkie powyższe katalogi
przed użyciem. W katalogu
ext/session znajduje się skrypt
mod_files.sh który przygotuje niezbędną strukturę
katalogów. Należy zauważyć, że używając N o wartości większej niż 0 nie
będzie przeprowadzane automatyczne sprzątanie śmieci. Więcej informacji
na ten temat znajduje się w pliku php.ini. Używając N należy także
pamiętać o otoczeniu wartości
session.save_path
"cudzysłowami", ponieważ separator (;
) jest używany
także do oznaczania komentarzy w php.ini.
Ostrzeżenie
Jeśli wartość tej zmiennej zostanie ustawiona na katalog odczytywalny
dla wszystkich użytkowników, jak na przykład /tmp
(domyślna wartość), inni użytkownicy systemu będą mogli "porwać" sesję
przez pobranie listy plików z tego katalogu.
Notatka:
W PHP starszym niż 4.3.6, użytkownicy systemu Windows musieli zmienić
wartość tej zmiennej aby korzystać z obsługi sesji. Musi być podana
poprawna ścieżka, na przykład c:/temp.
session.name
określa nazwę sesji, która zostanie użyta
jako nazwa ciasteczka. Powinna ona zawierać tylko znaki alfanumeryczne.
Domyślna wartość to PHPSESSID
.
Patrz także: session_name().
session.serialize_handler
określa nazwę podsystemu który
będzie użyty do serializowania/deserializowania danych. Aktualnie PHP
obsługuje wewnętrzny format (nazwa php
) i WDDX (nazwa
wddx
). WDDX jest dostępne tylko jeśli PHP zostało
skompilowane z obsługą WDDX. Domyślna
wartość to php
.
session.gc_probability
w połączeniu z
session.gc_divisor
jest używana do zarządzania
prawdopodobieństwem zdarzenia, że zostanie uruchomiony gc (garbage collector - sprzątacz
śmieci). Domyślna wartość to 1
. Więcej szczegółów
można znaleźć w opisie
session.gc_divisor.
session.gc_divisor
w połączeniu z
session.gc_probability
określa prawdopodobieństwo, z
jakim gc (garbage collector - sprzątacz śmieci) zostanie uruchomiony w
czasie inicjalizacji sesji. Prawdopodobieństwo jest określane przez
obliczenie gc_probability/gc_divisor, na przykład 1/100 oznacza, że jest
jednoprocentowa szansa, że proces sprzątania śmieci zostanie uruchomiony
na początku sesji.
Domyślna wartość session.gc_divisor
to 100
.
session.gc_maxlifetime
określa liczbę sekund, po
których dane zostaną uznane za "śmieci" i sprzątnięte.
Notatka:
Jeśli różne skrypty mają różne wartości
session.gc_maxlifetime
, ale współdzielą tą samą
przestrzeń do przechowywania danych sesyjnych, sprzątać będzie skrypt o
najmniejszej wartości tego parametru. W tym przypadku, należy użyć tej
dyrektywy razem z session.save_path.
Notatka:
Jeśli używany jest domyślny podsystem obsługi sesji oparty na plikach,
system plików musi śledzić czasy dostępu (atime). System plików FAT
używany w systemie Windows nie przechowuje takich informacji, a więc
niezbędne jest zapewnienie innego sposobu sprzątania śmieci sesji, jeśli
nie ma możliwości używania systemu innego niż FAT czy inny system plików
który nie śledzi czasu dostępu. Od PHP 4.2.3 używany jest mtime (czas
modyfikacji) zamiast atime. W związku z tym systemy plików nie śledzące
atime nie będą sprawiały problemów.
session.referer_check
zawiera element ciągu
tekstowego, który ma być sprawdzany w polu HTTP Referer. Jeśli klient
wysłał na główek Referer a podany element ciągu nie został w nim
znaleziony, to identyfikator sesji zostanie oznaczony jako nieprawidłowy.
Domyślna wartość to pusty ciąg.
session.entropy_file
określa ścieżkę do zewnętrznego
zasobu (pliku), który zostanie użyty jako dodatkowe źródło entropii przy
generowaniu identyfikatora sesji. Przykładowo może to być
/dev/random
lub /dev/urandom
, które
są dostępne na wielu systemach Uniksowych.
session.use_cookies
określa czy moduł będzie używał
ciasteczek do przechowywania identyfikatora sesji po stronie klienta.
Domyślna wartość to 1
(włączone).
session.use_only_cookies
określa czy moduł będzie
używał
tylko ciasteczek do przechowywania
identyfikatora sesji po stronie klienta.
Włączenie tej opcji zapobiega atakom związanym z przekazywaniem
identyfikatorów sesji w URLach. To ustawienie zostało dodane w PHP 4.3.0.
session.cookie_lifetime
określa czas życia ciasteczka
w sekundach, co zostanie przekazane do przeglądarki. Wartość 0 oznacza
"dopóki przeglądarka nie zostanie zamknięta". Domyślna wartość to
0
. Patrz także:
session_get_cookie_params() i
session_set_cookie_params().
session.cookie_domain
określa domenę użytą do
ustawienia ciasteczka sesyjnego. Domyślna wartość to brak domeny, co
oznacza nazwę serwera, który wygenerował ciasteczko, zgodnie ze
specyfikacją ciasteczek. Patrz także:
session_get_cookie_params() i
session_set_cookie_params().
session.cookie_secure
Określa czy ciasteczko powinno
być przesłane tylko poprzez bezpieczne połączenie. Domyślna wartość to
off
(wyłączone). Ta opcja została dodana w PHP 4.0.4.
Patrz także:
session_get_cookie_params() i
session_set_cookie_params().
session.cache_limiter
określa metodę kontroli pamięci
podręcznej użytą dla stron sesyjnych (dopuszczalne wartości to none,
nocache, private, private_no_expire, public). Domyślna wartość to
nocache
. Patrz także:
session_cache_limiter().
session.cache_expire
określa czas życia zbuforowanych
stron sesyjnych, określony w minutach (nie ma to efektu dla ogranicznika
nocache). Domyślna wartość to 180
. Patrz także:
session_cache_expire().
session.use_trans_sid
określa, czy włączona jest
obsługa przezroczystego przekazywania identyfikatora sesji. Domyślna
wartość to 0
(wyłączone).
Notatka:
W PHP 4.1.2 i starszych, opcja ta była włączana przez kompilację z
parametrem --enable-trans-sid. Od
PHP 4.2.0, trans-sid jest domyślnie wkompilowywane.
Zarządzanie sesjami oparte na URLu niesie za sobą więcej zagrożeń
bezpieczeństwa w stosunku do zarządzania opartego o ciasteczka.
Użytkownicy mogą wysyłać emailem do swoich przyjaciół URLe zawierające
identyfikatory sesji, lub też zapisywać je do zakładek i łączyć się z
danym serwerem zawsze przy użyciu tego samego identyfikatora.
PHP 4.2.3 i starsze miały nieudokumentowaną opcję/błąd, która pozwalała
na inicjalizację zmiennej sesyjnej w zasięgu globalnym pomimo wyłączenia
register_globals. PHP 4.3.0 i
nowsze wygenerują ostrzeżenie, jeśli ta opcja, a także
session.bug_compat_warn są
włączone naraz. Ta opcja/błąd może zostać wyłączona poprzez wyłączenie tej
dyrektywy.
PHP 4.2.3 i starsze miały nieudokumentowaną opcję/błąd, która pozwalała
na inicjalizację zmiennej sesyjnej w zasięgu globalnym pomimo wyłączenia
register_globals. PHP 4.3.0 i
nowsze wygenerują ostrzeżenie, jeśli obie opcje,
session.bug_compat_42 i
session.bug_compat_warn
zostaną włączone.
session.hash_function
pozwala na określenie algorytmu
skrótu, który zostanie użyty do generowania identyfikatora sesji.
'0' oznacza MD5 (128 bitów) a '1' oznacza SHA-1 (160 bitów).
session.hash_bits_per_character
pozwala na określenie
ile bitów jest przechowywanych w każdym znaku przy konwersji danych
binarnych na postać odczytywalną. Dopuszczalne wartości to '4' (0-9,
a-f), '5' (0-9, a-v) i '6' (0-9, a-z, A-Z, "-", ",").
url_rewriter.tags
określa które znaczniki HTML są
przepisywane w celu dodania identyfikatora sesji jeśli włączona jest
opcja przezroczystego przekazywania identyfikatora. Domyślna wartość to
a=href,area=href,frame=src,input=src,form=fakeentry,fieldset=
Notatka:
Aby uzyskać zgodność z XHTML, należy usunąć wpis form
i użyć znaczników <fieldset> wokół pól formularza.
Poniższe stałe są zdefiniowane w tym rozszerzeniu i stają się dostępne, gdy
rozszerzenie jest dokompilowane do PHP, lub załadowane dynamicznie przy starcie.
Stała zawierająca albo nazwę sesji i jej identyfikator w postaci
"name=ID"
lub pusty ciąg tekstowy jeśli identyfikator
sesji został ustawiony przez prawidłowe ciasteczko sesyjne.
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, nie
ma konieczności stosowania słowa kluczowego global dla
zmiennej $_SESSION
. Należy pamiętać, że dokumentacja
została zmieniona tak, aby zalecać stosowanie wszędzie
$_SESSION
. Możliwa jest jednak zamiana
$_SESSION
na $HTTP_SESSION_VARS
,
zależnie od preferencji. Należy także zauważyć, że aby zmienna
$_SESSION
była dostępna, niezbędne jest rozpoczęcie
sesji poprzez użycie funkcji session_start().
Klucze tablicy asocjacyjnej $_SESSION
podlegają tym
samym ograniczeniom co nazwy zwykłych zmiennych w PHP, tzn. nie mogą
rozpoczynać się od liczby i muszą rozpoczynać się od litery lub znaku
podkreślenia. Więcej szczegółów można znaleźć w rozdziale
zmienne.
Jeśli opcja register_globals
jest wyłączona, tylko pozycje należące do zmiennej asocjacyjnej
$_SESSION
mogą być zarejestrowane jako
zmienne sesyjne. Odtworzone zmienne sesyjne będą dostępne tylko w zmiennej
$_SESSION
.
Użycie $_SESSION
(lub
$HTTP_SESSION_VARS
dla wersji PHP 4.0.6 i starszych)
jest wskazane ze względów poprawionego bezpieczeństwa i czytelności kodu. Używając
$_SESSION
nie ma potrzeby używać funkcji
session_register()(),
session_unregister()() czy
session_is_registered()(). Zmienne sesyjne są dostępne
tak jak wszystkie inne zmienne.
Przykład 1.
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 2.
Wyrejestrowywanie zmiennej korzystając z $_SESSION
przy wyłączonej dyrektywie register_globals
<?php session_start() // Użyj $HTTP_SESSION_VARS dla PHP 4.0.6 i starszych unset($_SESSION['count']); ?>
Uwaga!
Nie należy usuwać całej tablicy $_SESSION
wyrażeniem
unset($_SESSION)
, jako że uniemożliwi to
rejestrowanie zmiennych sesyjnych poprzez tablicę superglobalną
Ostrzeżenie
W sesjach nie jest możliwe zapisywanie referencji, jako że nie ma
sensownej metody przywracania referencji do innych zmiennych.
Jeśli włączona jest dyrektywa register_globals, każda globalna
zmienna może zostać zarejestrowana jako zmienna sesyjna. Po restarcie
sesji, zmienne te są przywracane jako odpowiednie zmienne globalne.
Ponieważ PHP musi wiedzieć które zmienne są zarejestrowane jako zmienne
sesji, nalezy je zarejestrować poprzez funkcję
session_register(). Etap ten można pominąć poprzez
dodawanie wpisów do tablicy $_SESSION
.
Jeśli dyrektywa register_globals jest włączona, to
zmienne globalne i wpisy w tablicy $_SESSION
automatycznie wskazują na tą samą wartość, która została zarejestrowana w
poprzedniej instancji sesji. Jednakże jeśli zmienna została
zarejestrowana poprzez tablicę $_SESSION
, to zmienna
globalna dostępna jest dopiero w następnym wywołaniu.
PHP w wersji 4.2.3 i wcześniejszych posiada pewien błąd. Przy rejestracji
w sesji nowej zmiennej poprzez funkcję
session_register(), wpis w zasięgu globalnym i wpis w
$_SESSION
nie będą referencjami do tej samej wartości
do czasu następnego wywołania session_start(). Na
przykład, modyfikacja nowo zarejestrowanej zmiennej globalej nie znajdzie
odbicia we wpisie w tablicy $_SESSION
. Błąd ten został
poprawiony w PHP 4.3.
Istnieją dwie metody propagacji identyfikatora sesji:
Ciasteczka
Parametry URL'a
Moduł sesji obsługuje obie metody. Ciasteczka są metodą optymalną, ale
jako że nie są one zawsze dostępne, zapewniona jest także metoda
alternatywna. Metoda ta polega na dopisywaniu identyfikatora bezpośrednio
do adresu URL.
PHP jest zdolne do przezroczystego przetwarzania odnośników. Używając PHP
w wersji wcześniejszej niż 4.2, niezbędne jest ręczne włączenie tej opcji
przy kompilacji. W systemach Unix, należy dodać parametr
--enable-trans-sid przy konfiguracji
kompilacji. Jeśli PHP zostanie skompilowane z tą opcją, a także włączona
zostanie dyrektywa konfiguracji session.use_trans_sid
,
wszystkie względne adresy URI zostaną automatycznie poprawione tak, aby
zawierały identyfikator sesji.
Notatka:
Dyrektywa arg_separator.output
, którą można umieścić w pliku konfiguracyjnym php.ini, pozwala
ustawić własny separator argumentów. Dla zachowania pełnej zgodności ze
standardem XHTML, należy w tym miejscu podać wartość &.
Możliwe jest także zastosowanie stałej SID
, która jest
definiowana w momencie rozpoczęcia sesji. Jeśli klient nie przesłał
poprawnego ciasteczka sesyjnego, stała ta ma postać
nazwa_sesji=id_sesji
. W przeciwnym przypadku jest to
pusty ciąg. W związku z tym, stała ta może być wstawiona do adresów bez
konieczności stosowania instrukcji warunkowych.
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 3. Zliczanie ilości odwiedzin pojedyńczego użytkownika
<p> Witaj gościu. Oglądasz tą stronę <?php echo $count; ?> raz. </p>
<p> Aby kontynuować, <a href="nextpage.php?<?php echo strip_tags(SID); ?>">kliknij tutaj</A> </p>
Funkcja strip_tags() została zastosowana w celu
zapobieżenia atakom typu XSS.
Dodawanie stałej SID do adresów, jak to zostało zrobione w powyższym
przykładzie, nie jest konieczne, jeśli PHP zostało skompilowane z opcją
--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, należy użyć
session_set_save_handler() do stworzenia zestawu
funkcji przechowujących dane.