CZĘŚĆ 20
Architektura aplikacji, wzorzec PRG i standard PDO
PPrezentacja dla nauczyciela
W realnych projektach oraz zaawansowanych arkuszach egzaminacyjnych kod nie może być zbiorem przypadkowych instrukcji. W tej części poznasz wzorzec PRG (Post-Redirect-Get) eliminujący problem podwójnego wysyłania formularza po odświeżeniu strony, nauczysz się przekazywać jednorazowe powiadomienia (Flash messages) w sesji oraz poznasz PDO — nowoczesny, obiektowy standard komunikacji z bazami danych stosowany w branży IT.
Podział aplikacji na pliki
Zamiast jednego długiego pliku dzielimy aplikację na części: konfigurację połączenia, funkcje pomocnicze i osobne strony widoków. Dzięki temu tę samą bazę i funkcje wykorzystuje wiele podstron.
Pliki współdzielone dołączamy przez require (błąd zatrzymuje skrypt) lub include (błąd daje ostrzeżenie). W praktyce bezpieczniej używać require_once.
Warto trzymać konfigurację poza katalogiem publicznym. Plik z hasłem do bazy nie powinien być dostępny pod adresem w przeglądarce.
require_once __DIR__ . '/config.php';
require_once __DIR__ . '/funkcje.php';
$pdo = new PDO('mysql:host=' . DB_HOST . ';dbname=' . DB_NAME, DB_USER, DB_PASS, [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
]);
$uczniowie = $pdo->query('SELECT imie FROM uczniowie')->fetchAll();
Wzorzec POST-Redirect-GET
Po zapisie danych z formularza przekierowujemy użytkownika na inną stronę. Wzorzec nazywa się POST-Redirect-GET i chroni przed ponownym wysłaniem formularza po odświeżeniu.
Schemat jest prosty: odbierz POST, zapisz dane, ustaw komunikat w sesji i wywołaj header('Location: ...'), a potem exit. Na stronie docelowej odczytaj i usuń komunikat.
Komunikat w sesji nazywa się często „flash”. Dzięki niemu po przekierowaniu nadal można pokazać informację o sukcesie.
session_start();
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// zapis danych
$_SESSION['komunikat'] = 'Zapisano zgloszenie';
header('Location: lista.php');
exit;
}
$komunikat = $_SESSION['komunikat'] ?? '';
unset($_SESSION['komunikat']);
echo $komunikat ? '<p>' . $komunikat . '</p>' : '';
PDO, wyjątki i transakcje
PDO to wspólny interfejs do różnych baz. Dzięki temu kod wygląda tak samo dla MySQL i SQLite, a zapytania przygotowane są domyślnie dostępne.
Tryb wyjątków (ERRMODE_EXCEPTION) sprawia, że błąd bazy przerywa skrypt i można go obsłużyć w try/catch. To czytelniejsze niż sprawdzanie wyniku po każdym zapytaniu.
Transakcja grupuje kilka operacji: beginTransaction(), potem zapytania, na końcu commit() albo rollBack() przy błędzie. Dzięki temu dane nie zostaną zapisane połowicznie.
try {
$pdo->beginTransaction();
$pdo->prepare('INSERT INTO zamowienia (klient) VALUES (?)')->execute(['Ola']);
$pdo->prepare('UPDATE stany SET sztuk = sztuk - 1 WHERE id = ?')->execute([3]);
$pdo->commit();
echo 'Zapisane';
} catch (Throwable $e) {
$pdo->rollBack();
echo 'Blad zapisu';
}
Ćwiczenia
- 1Centralny plik połączenia (require_once)require_once db.php i modularnośćZadanie i podpowiedzi →
- 2Rozdzielenie logiki od widoku (Separation of Concerns)przygotowanie danych przed HTMLZadanie i podpowiedzi →
- 3Pierwsze przekierowanie nagłówkiem (header i exit)header Location i exitZadanie i podpowiedzi →
- 4Wzorzec PRG z parametrem statusu w adresiePost-Redirect-Get w formularzuZadanie i podpowiedzi →
- 5Komunikat Flash w sesji (jednorazowe powiadomienie)jednorazowe powiadomienie unsetZadanie i podpowiedzi →
- 6Formularz z zachowaniem wpisanych wartości (Sticky Form)Sticky Form po błędzie walidacjiZadanie i podpowiedzi →
- 7Bezpieczne usuwanie akcją POST z PRGusuwanie z bazy i przekierowanieZadanie i podpowiedzi →
- 8Kompletny obieg PRG z bazą i komunikatem flashpełen cykl PRG z sesją i baząZadanie i podpowiedzi →
- 9Pierwsze połączenie przez PDO (new PDO i DSN)new PDO, DSN i ERRMODEZadanie i podpowiedzi →
- 10Prosty odczyt danych w PDO (query i fetchAll)query i fetchAll FETCH_ASSOCZadanie i podpowiedzi →
- 11Odczyt pojedynczego wyniku (fetch i fetchColumn)fetchColumn oraz pojedynczy fetchZadanie i podpowiedzi →
- 12Zapytanie przygotowane w PDO ze znakiem zapytania (?)prepare i execute z tablicąZadanie i podpowiedzi →
- 13Parametry nazwane w PDO (:nazwa)czytelne zapytania z dwukropkiemZadanie i podpowiedzi →
- 14Wstawianie rekordu w PDO i pobranie ID (lastInsertId)INSERT z odczytem nowego IDZadanie i podpowiedzi →
- 15Aktualizacja danych i kontrola zmian (rowCount)UPDATE z kontrolą liczby zmianZadanie i podpowiedzi →
- 16Finałowa synteza PRG i PDOnowoczesna aplikacja PRG + PDOZadanie i podpowiedzi →