Sesje i ciasteczka — zapamiętaj użytkownika

🎯 Po tej lekcji uruchomisz sesję, zapiszesz i odczytasz dane z $_SESSION oraz ustawisz ciasteczko — i będziesz wiedzieć, kiedy wybrać sesję, a kiedy cookie.

Do tej pory każde żądanie HTTP było jak rozmowa z amnezją — serwer odpowiadał i natychmiast zapominał, kto pytał. Sesje i ciasteczka to mechanizmy, które pozwalają serwerowi „zapamiętać" użytkownika między kolejnymi żądaniami.

Czym jest sesja?

Wyobraź sobie numerek w przychodni: dostajesz go przy wejściu i okazujesz przy każdym okienku. Sesja PHP działa podobnie:

  1. Przy pierwszym wejściu serwer tworzy unikalny identyfikator sesji (np. abc123xyz)
  2. Wysyła go do przeglądarki jako ciasteczko PHPSESSID
  3. Przeglądarka dołącza PHPSESSID do każdego kolejnego żądania
  4. PHP odczytuje identyfikator i wznawia sesję — razem ze wszystkimi zapisanymi danymi

Dane sesji siedzą na serwerze, nie w przeglądarce.

session_start() — obowiązkowy początek

Zanim cokolwiek zrobisz z sesją, musisz ją zainicjować. session_start() musi być wywołana przed wysłaniem jakiegokolwiek wyjścia — nawet przed pierwszym tagiem HTML:

<?php
declare(strict_types=1);

session_start(); // ZAWSZE pierwsze — przed echo, przed HTML

$_SESSION['imie'] = 'Ola';

echo htmlspecialchars($_SESSION['imie'], ENT_QUOTES, 'UTF-8'); // wynik: Ola
⚠️ Headers already sent: Jeśli zapomnisz o session_start() przed wyjściem, PHP zgłosi błąd: Cannot modify header information — headers already sent. Nagłówki HTTP (w tym ID sesji) muszą dotrzeć do przeglądarki przed treścią strony.

Zapisywanie i odczytywanie $_SESSION

$_SESSION to zwykła tablica asocjacyjna — możesz zapisywać i odczytywać dowolne wartości:

<?php
declare(strict_types=1);

session_start();

// Zapisz dane w sesji
$_SESSION['imie']    = 'Kuba';
$_SESSION['licznik'] = ($_SESSION['licznik'] ?? 0) + 1;

// Odczytaj dane
$imie    = $_SESSION['imie']    ?? 'gość';
$licznik = $_SESSION['licznik'] ?? 0;

echo htmlspecialchars($imie, ENT_QUOTES, 'UTF-8');
// wynik: Kuba

echo 'Odwiedzasz stronę po raz: ' . $licznik;
// wynik po trzecim wejściu: Odwiedzasz stronę po raz: 3

Dane sesji przetrwają kolejne żądania — ale znikają, gdy przeglądarka zostanie zamknięta (ciasteczko PHPSESSID jest domyślnie sesyjne) lub gdy wywołasz session_destroy().

Licznik odwiedzin — praktyczny przykład

<?php
declare(strict_types=1);

session_start();

$_SESSION['odwiedziny'] = ($_SESSION['odwiedziny'] ?? 0) + 1;
$odwiedziny = $_SESSION['odwiedziny'];
?>
<!DOCTYPE html>
<html lang="pl">
<head><meta charset="UTF-8"><title>Licznik</title></head>
<body>
    <p>Odwiedzasz tę stronę po raz: <?= (int) $odwiedziny ?>.</p>
</body>
</html>

Odśwież stronę kilka razy — licznik będzie rósł. Zamknij przeglądarkę i wejdź ponownie — zacznie od 1.

setcookie() — ciasteczka w przeglądarce

Ciasteczko to mała porcja danych przechowywana w przeglądarce użytkownika. Serwer wysyła ciasteczko przez nagłówek HTTP, a przeglądarka dołącza je do każdego kolejnego żądania do tej samej domeny.

Kluczowa różnica wobec sesji: ciasteczko może przetrwać wiele dni — nawet po zamknięciu przeglądarki.

<?php
declare(strict_types=1);

// Musi być PRZED jakimkolwiek wyjściem
setcookie(
    'imie',                    // nazwa ciasteczka
    'Jan',                     // wartość (tylko string)
    time() + 30 * 24 * 3600,  // wygasa za 30 dni
    '/',                       // dostępne na całej stronie
    '',                        // domena: bieżąca
    false,                     // tylko HTTPS? (true na produkcji)
    true                       // httponly: ciasteczko niedostępne dla JS
);

Odczyt następuje przez $_COOKIE — ale dopiero od następnego żądania:

<?php
declare(strict_types=1);

// Odczytaj ciasteczko ustawione wcześniej
$imie = $_COOKIE['imie'] ?? 'gościu';
echo 'Witaj, ' . htmlspecialchars($imie, ENT_QUOTES, 'UTF-8') . '!';
// wynik: Witaj, Jan! (od drugiego żądania)

Sesja czy ciasteczko?

| | Sesja | Ciasteczko | |---|---|---| | Gdzie siedzą dane | Na serwerze | W przeglądarce | | Domyślny czas życia | Do zamknięcia przeglądarki | Kontrolujesz (sekundy → lata) | | Pojemność | Praktycznie nieograniczona | ~4 KB na ciasteczko | | Bezpieczeństwo | Dane nie opuszczają serwera | Dane widoczne w przeglądarce | | Kiedy użyć | Koszyk, dane logowania, tymczasowe dane | Preferencje użytkownika, „zapamiętaj mnie" |

💡 httponly = true: Zawsze ustawiaj httponly na true przy ciasteczkach z danymi sesji lub identyfikatorami. Uniemożliwia odczyt ciasteczka przez JavaScript — chroni przed atakami XSS kradnącymi sesję.

W Module 9 nauczysz się pełnego logowania z hasłami. Na razie masz już wszystkie fundamenty — a w kolejnej lekcji połączysz je w mini-projekt: własną księgę gości.

Funkcje w tej lekcji

Sprawdź się

Kiedy należy wywołać session_start()?

Jaka jest główna różnica między sesją a ciasteczkiem?

Kiedy ciasteczko ustawione przez setcookie() staje się dostępne w $_COOKIE?

Ćwiczenie

Napisz skrypt licznika odwiedzin korzystający z sesji. Przy każdym odświeżeniu strony licznik ma wzrastać o 1. Wyświetl komunikat: 'Witaj! Odwiedzasz tę stronę po raz: X.' Dodaj przycisk 'Resetuj licznik', który zeruje sesję.

Pokaż rozwiązanie
<?php
declare(strict_types=1);

session_start();

// Resetuj licznik na żądanie
if (isset($_POST['resetuj'])) {
    $_SESSION['licznik'] = 0;
}

// Zwiększ licznik
$_SESSION['licznik'] = ($_SESSION['licznik'] ?? 0) + 1;
$licznik = $_SESSION['licznik'];
?>
<!DOCTYPE html>
<html lang="pl">
<head><meta charset="UTF-8"><title>Licznik</title></head>
<body>
    <p>Witaj! Odwiedzasz tę stronę po raz: <?= (int) $licznik ?>.</p>
    <form method="post" action="">
        <button type="submit" name="resetuj">Resetuj licznik</button>
    </form>
</body>
</html>