INF.03 · Aplikacje internetowe PHP
Koszyk zakupowy w sesji
Koszyk: ID i ilość, nie cena z formularza.
- PHP8.3
- mysqli · MariaDB
- Praktyka i diagnoza
Po tej lekcji: Zapiszesz ograniczony koszyk w sesji i obliczysz jego zawartość na podstawie rekordów bazy.
Zrozum mechanizm
W sesji koszyk jest mapą idFilmu=>ilosc. Dodanie i usunięcie to POST z tokenem. Sprawdź istnienie ID w bazie, zakres ilości i liczbę pozycji. W tym modelu maksimum to 20 różnych filmów i 10 sztuk każdego. Count(koszyk) podaje różne pozycje; suma ilości to inne pytanie.
Cena jest odczytywana z bazy. Ukryte pole cena nie jest zaufane — użytkownik może je zmienić. Zamiana ID na produkt z publicznego katalogu jest normalnym wyborem, ale zmiana własności danych czy ceny już nie. Kwoty mnożymy jako grosze. Jeśli rekord zniknie z bazy, podgląd nie powinien powodować błędu, a finalizacja musi ponownie sprawdzić wszystkie pozycje.
Jak uruchamiać krótkie przykłady?
Każdy krótki przykład oznaczony własnym plikiem uruchamiaj osobno, nie doklejaj wszystkich definicji do jednego pliku. W edytorze zapisz go jako .php, a w terminalu tego folderu wpisz np. php for.php. Wtedy pokazane końce wierszy PHP_EOL są widoczne. W odpowiedzi HTML znak końca wiersza sam nie robi nowej linii na ekranie: użyj <br> albo znacznika <pre>. Wyświetl źródło pozwala zobaczyć tekst odpowiedzi.
Przykłady opisane jako fragment projektu wymagają paczki KINO / LAB i wcześniejszej konfiguracji. Nie uruchamiaj ich jako samodzielnych endpointów. Pełny plik niżej pokazuje kontekst. Funkcje h(), pole() i wymagajPost() są nasze; ich definicje wczytuje bootstrap.php.
Koszyk: klucz to ID filmu, wartość to ilość
Najpierw prześledź na zwykłej tablicy, bez bazy. ID 7 i 12 są kluczami; wartości 2 i 1 są liczbami sztuk, nie cenami.
Podstawowa forma: $_SESSION["koszyk"][idFilmu] = ilosc;
<?php
$koszyk = [7 => 2, 12 => 1];
$koszyk[7] = ($koszyk[7] ?? 0) + 1;
$sztuki = 0;
foreach ($koszyk as $id => $ilosc) {
$sztuki += $ilosc;
echo "$id: $ilosc" . PHP_EOL;
}
echo 'Pozycje: ' . count($koszyk) . ', sztuki: ' . $sztuki;
7: 3 12: 1 Pozycje: 2, sztuki: 4
- Odczytujemy dotychczasową ilość filmu 7, dodajemy 1 i zapisujemy 3. Dla nowego klucza ?? dałoby 0.
- foreach as id=>ilosc oddziela identyfikator od liczby sztuk. += dodaje do dotychczasowej sumy.
- count daje 2 różne pozycje, suma ilości daje 4 sztuki. Właśnie dlatego count nie wystarcza do pytania „ile biletów?”.
- W pełnym projekcie tablica jest w $_SESSION.
??= []tworzy pusty koszyk tylko dla braku/null, min(10, wartosc) ogranicza ilość; cenę zawsze odczytuje serwer z bazy.
Jak czytać pozostałe zapisy w pełnym przykładzie
| Zapis | Znaczenie | Przykład użycia |
|---|---|---|
pole($dane, $nazwa) | Nasza funkcja: pobiera wskazany klucz tylko wtedy, gdy ma wartość string; inaczej oddaje pusty napis. isset sprawdza obecność i brak null, is_string typ. | pole($_POST, "email") |
wymagajPost() | Nasza funkcja: sprawdza metodę POST oraz CSRF; przy błędzie przerywa odpowiedź z405/403. | wymagajPost(); |
wymagajLogowania() | Nasza funkcja: oddaje int ID konta z sesji lub przekierowuje do logowania. | $id = wymagajLogowania(); |
przekieruj($adres) | Nasza funkcja wysyła Location ze statusem303 i kończy wykonanie przez exit. Typ wyniku never oznacza, że nie wraca do dalszej instrukcji. | przekieruj("/panel.php"); |
dirname(__DIR__) | dirname daje katalog nadrzędny; __DIR__ to katalog bieżącego pliku. W public prowadzi to do katalogu projektu, a dopisana ścieżka wskazuje src. | dirname(__DIR__)."/src/bootstrap.php" |
$_SESSION i $_POST | Specjalne tablice PHP: pierwsza to stan sesji, druga dane formularza POST. Zewnętrzne wartości trzeba sprawdzić, nie ufać samym nazwom kluczy. | $_SESSION["user_id"] |
?? i ??= | a ?? b wybiera b dla braku/null; a ??= b zapisuje b tylko, gdy a nie istnieje lub ma null. Nie reagują na0 ani pusty napis. | $_SESSION["koszyk"] ??= []; |
===, !==, &&, ||, ! | Identyczne, nieidentyczne, i, lub, zaprzeczenie. Porównanie ścisłe obejmuje typ; &&/|| nie sprawdzają drugiej części, gdy wynik jest już rozstrzygnięty. | $rok === false || $rok < 1888 |
-> oraz :: | -> wybiera właściwość lub metodę obiektu; :: odnosi się do elementu statycznego klasy. To nie jest zapis dostępu do tablicy. | $zapytanie->execute(); |
Sprawdź w działaniu
Koszyk: ID i ilość, nie cena z formularza — sprawdź w modelu
Model w przeglądarce wyjaśnia mechanizm na fikcyjnych danych. Nie wykonuje PHP ani zapytań SQL i nie tworzy kont. Prawdziwe skrypty uruchomisz lokalnie z paczki.
Przewidź rezultat, wykonaj próbę i wyjaśnij, która decyzja po stronie serwera decyduje o wyniku.
Uruchom krok po kroku
Zaloguj się, dodaj Podróż dwa razy i Kosmos raz. Otwórz koszyk: są 2 różne filmy,3 sztuki i 4197 groszy. Usuń jedną pozycję. Porównaj sesję ze źródłem cen w SELECT. Nie wypisuj pełnej sesji z danymi logowania do odpowiedzi.
Zmiana zawartości koszyka przez POST
<?php
require_once dirname(__DIR__).'/src/db.php';
wymagajLogowania();
$_SESSION['koszyk'] ??= [];
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
wymagajPost();
$id = filter_var(pole($_POST, 'id'), FILTER_VALIDATE_INT);
$akcja = pole($_POST, 'akcja');
if ($id === false || $id < 1 || ! in_array($akcja, ['dodaj', 'usun'], true)) {
http_response_code(422);
exit('Nieprawidłowa operacja koszyka.');
}
$sprawdz = $polaczenie->prepare('SELECT id FROM Filmy WHERE id=?');
$sprawdz->bind_param('i', $id);
$sprawdz->execute();
if (! $sprawdz->get_result()->fetch_assoc()) {
http_response_code(404);
exit('Brak filmu.');
}
if ($akcja === 'usun') {
unset($_SESSION['koszyk'][$id]);
} else {
if (count($_SESSION['koszyk']) >= 20 && ! isset($_SESSION['koszyk'][$id])) {
http_response_code(422);
exit('Maksymalnie20 różnych filmów.');
}
$_SESSION['koszyk'][$id] = min(10, ($_SESSION['koszyk'][$id] ?? 0) + 1);
}
unset($_SESSION['zamowienie_klucz']);
przekieruj('/koszyk.php');
}
Pobierz i odtwórz projekt
W „Źródłach i materiałach” na końcu pobierz KINO / LAB.zip. Rozpakuj całość; instrukcja START.txt opisuje konfigurację. Pierwsze 6 przykładów w public/podstawy działa bez bazy. Dalsze wymagają lokalnej MariaDB 11.4, importu schema.sql i lokalnego konta bazy z minimalnymi prawami. Gotowa paczka pokazuje całość, ale w tej lekcji wykonaj opisane kroki i własne zadanie.
Ćwiczenie z pomocą · samodzielna praca
Twoja próba — podpowiedzi otwieraj po kolei
Dodaj 2×Podróż i 1×Kosmos, usuń Kosmos, potem spróbuj nieistniejącego ID.
Najpierw 4197 groszy, potem 2598; błędny ID daje 404 i nie zmienia koszyka.
? Potrzebujesz pomocy? Rozwiązuj krok po kroku.
Krok 1 — pokaż podpowiedź
Odszukaj wskazany plik i zapisz przewidywany rezultat przed zmianą.
Krok 2 — pokaż podpowiedź
Zmień jedną rzecz. Sprawdź metodę żądania, dane i odpowiedź lub wynik programu.
Krok 3 — pokaż podpowiedź
Wykonaj próbę graniczną lub błędną. Porównaj także stan bazy lub sesji, nie tylko komunikat.
Otwórz tylko tyle podpowiedzi, ile potrzebujesz. Po każdym kroku wróć do zadania i sprawdź wynik.
Podsumowanie
Co warto zapamiętać
- Zapiszesz ograniczony koszyk w sesji i obliczysz jego zawartość na podstawie rekordów bazy.
- Potrafisz wskazać w kodzie przyczynę wyniku i zaplanować próbę błędnych danych.
- Nie oddajesz haseł, pliku config.local.php ani wartości cookie.
Dalej na swoim koncie
Rozgrzewki, quiz i zadania są w biurku ucznia.
Teoria jest otwarta dla wszystkich. Żeby rozwiązywać zadania, zapisywać szkice i widzieć swój postęp, zaloguj się.
Zaloguj się →