Dane z formularza zawsze trzeba sprawdzić na serwerze — przeglądarkę można ominąć, a pole „wiek” może dojść jako tekst abc, pusty napis albo liczba z kosmosu. Walidacja w PHP polega na sprawdzeniu każdego pola według reguł i zebraniu komunikatów o błędach, które zostaną pokazane użytkownikowi. Na lekcji uczniowie piszą funkcję waliduj i testują ją na zestawach danych.
Scenariusz jest przeznaczony na 45 minut dla klasy znającej tablice i funkcje w PHP oraz formularze — na przykład po lekcji o formularzach PHP i lekcji o funkcjach.
Przygotowanie stanowisk
Potrzebny jest PHP 8.x uruchamiany w terminalu (na przykład z pakietu XAMPP; sprawdź polecenie php -v). Rozpakuj pakiet z sekcji materiałów do osobnego folderu i przejdź do niego w terminalu. Skrypty uruchamiasz poleceniem php start.php; serwer WWW nie jest potrzebny, a wynik pojawia się w terminalu. Jeśli pobierasz pojedyncze pliki .php.txt ze strony zamiast ZIP, usuń końcówkę .txt lokalnie.
Cele i plan lekcji
Po zajęciach uczeń potrafi:
- sprawdzić długość tekstu po usunięciu spacji (
trim,mb_strlen); - sprawdzić adres e-mail i liczbę całkowitą z zakresem funkcją
filter_var; - sprawdzić, czy wartość należy do listy dozwolonych (
in_arrayw trybie ścisłym); - zebrać błędy w tablicy według nazw pól i wypisać je bezpiecznie.
| Czas | Praca na lekcji |
|---|---|
| 0–5 min | Problem: dane, którym nie można ufać |
| 5–15 min | trim, mb_strlen, filter_var |
| 15–22 min | Lista błędów według pól |
| 22–37 min | Trzy zadania samodzielne |
| 37–42 min | Przypadki brzegowe |
| 42–45 min | Pytania kontrolne |
Reguły walidacji
Dane z formularza trafiają do PHP jako teksty ($_POST, $_GET), a pola mogą w ogóle nie dojść — dlatego każdy odczyt zabezpieczamy operatorem ??. Funkcja waliduj(array $dane): array zwraca tablicę błędów, w której kluczem jest nazwa pola; pusta tablica oznacza dane poprawne.
- Tekst:
trimusuwa spacje z początku i końca, amb_strlenliczy znaki (zwykłestrlenliczy bajty, więc polskie litery liczyłby podwójnie). - E-mail:
filter_var($email, FILTER_VALIDATE_EMAIL)zwraca adres lubfalse. Sprawdza format, a nie istnienie adresu. - Liczba całkowita:
filter_var($wiek, FILTER_VALIDATE_INT, ["options" => ["min_range" => 10, "max_range" => 99]])zwraca liczbę lubfalse; odrzuca ułamki ("16.5"), litery i pusty tekst. Uwaga: poprawne0też jest wartością „fałszywą”, dlatego wynik porównujemy zfalseściśle (=== false). - Lista dozwolonych wartości:
in_array($klasa, ["1", "2", "3", "4"], true)— ostatni argument włącza porównanie ścisłe.
Komunikaty wypisujemy z htmlspecialchars, bo mogą zawierać dane użytkownika. Walidacja po stronie serwera jest obowiązkowa; atrybuty required i pattern w HTML tylko ułatwiają pracę użytkownikowi.
Zadania
Zadanie 1. Poprawne dane. Napisz waliduj(array $dane): array sprawdzającą pola imie (co najmniej 2 znaki po trim), email, wiek (10–99) i klasa (1–4). Sprawdź dane ["imie" => "Ola", "email" => "ola@example.com", "wiek" => "16", "klasa" => "2"] — liczba błędów ma wynosić 0.
Zadanie 2. Błędne dane. Sprawdź ["imie" => " O ", "email" => "ola@", "wiek" => "9", "klasa" => "7"] i wypisz komunikat dla każdego pola.
Zadanie 3. Brakujące pola i wiek. Wypisz nazwy pól z błędami dla danych zawierających tylko imię. Sprawdź filter_var z zakresem dla wartości "16", "9", "100", "16.5", "abc" i pustego tekstu oraz wypisz znaczniki HTML bezpiecznie.
Dla chętnych: sprawdź funkcją filter_var adresy a@b.pl, a@b, @b.pl i a b@c.pl.
Rozwiązanie i wyniki
<?php
function waliduj(array $dane): array
{
$bledy = [];
$imie = trim((string) ($dane["imie"] ?? ""));
if (mb_strlen($imie) < 2) {
$bledy["imie"] = "Imie musi miec co najmniej 2 znaki.";
}
$email = trim((string) ($dane["email"] ?? ""));
if (filter_var($email, FILTER_VALIDATE_EMAIL) === false) {
$bledy["email"] = "Podaj poprawny adres e-mail.";
}
$wiek = filter_var($dane["wiek"] ?? "", FILTER_VALIDATE_INT, ["options" => ["min_range" => 10, "max_range" => 99]]);
if ($wiek === false) {
$bledy["wiek"] = "Wiek to liczba od 10 do 99.";
}
if (!in_array($dane["klasa"] ?? "", ["1", "2", "3", "4"], true)) {
$bledy["klasa"] = "Wybierz klase od 1 do 4.";
}
return $bledy;
}
// Zadanie 1
$poprawne = ["imie" => "Ola", "email" => "ola@example.com", "wiek" => "16", "klasa" => "2"];
echo count(waliduj($poprawne)), "\n";
// Zadanie 2
$bledne = ["imie" => " O ", "email" => "ola@", "wiek" => "9", "klasa" => "7"];
foreach (waliduj($bledne) as $pole => $komunikat) {
echo $pole, ": ", $komunikat, "\n";
}
// Zadanie 3
echo implode(",", array_keys(waliduj(["imie" => "Jan"]))), "\n";
foreach (["16", "9", "100", "16.5", "abc", ""] as $wiek) {
$ok = filter_var($wiek, FILTER_VALIDATE_INT, ["options" => ["min_range" => 10, "max_range" => 99]]);
echo var_export($wiek, true), " ", $ok === false ? "zly" : "ok", "\n";
}
echo htmlspecialchars("<b>zle</b>", ENT_QUOTES, "UTF-8"), "\n";
Program wypisze:
0
imie: Imie musi miec co najmniej 2 znaki.
email: Podaj poprawny adres e-mail.
wiek: Wiek to liczba od 10 do 99.
klasa: Wybierz klase od 1 do 4.
email,wiek,klasa
'16' ok
'9' zly
'100' zly
'16.5' zly
'abc' zly
'' zly
<b>zle</b>
Dla danych z samym imieniem (["imie" => "Jan"]) wszystkie pozostałe pola zgłaszają błąd, bo ich brak jest traktowany jak pusty tekst. Zadanie dla chętnych (rozszerzenie.php) wypisuje:
a@b.pl ok
a@b zly
@b.pl zly
a b@c.pl zly
Typowe błędy
| Objaw | Co sprawdzić |
|---|---|
| Warning: Undefined array key | Odczyt pola, którego nie przysłano; użyj ?? "". |
| Wiek 0 uznany za błąd mimo zakresu zawierającego 0 | Wynik filter_var porównano luźno (!$wiek) zamiast === false. |
| Polskie imię z dwoma znakami uznane za zbyt krótkie | Użyto strlen, która liczy bajty; mb_strlen liczy znaki. |
Błąd w in_array mimo poprawnej klasy | Brak trybu ścisłego (true) albo porównywanie liczby z tekstem. |
| E-mail ze spacjami odrzucony | Brakuje trim przed filter_var. |
Komunikat zawiera znaki < i psuje stronę | Komunikat z danymi użytkownika wypisano bez htmlspecialchars. |
Pytania kontrolne i punktacja
- Dlaczego walidacja tylko w przeglądarce nie wystarcza?
- Czym różni się
strlenodmb_strlen? - Co zwróci
filter_var("abc", FILTER_VALIDATE_INT)?
Odpowiedzi: Bo użytkownik może ominąć kod w przeglądarce i wysłać dowolne dane bezpośrednio na serwer. strlen liczy bajty, mb_strlen — znaki. false.
Proponowana punktacja (razem 10 punktów): zadanie 1 — funkcja z czterema regułami 3 pkt, wynik dla danych poprawnych 1 pkt; zadanie 2 — cztery komunikaty 2 pkt; zadanie 3 — brakujące pola 1 pkt, filter_var z zakresem 2 pkt, htmlspecialchars 1 pkt. Zadanie dla chętnych nie jest wymagane do pełnej oceny.
Materiały do pobrania
Rozpakuj ZIP przed otwarciem plików. Materiały są dostępne bez logowania; publiczne rozwiązanie służy nauce i samodzielnemu sprawdzeniu, a nie poufnemu sprawdzianowi.
Co dalej?
Następny krok to ponowne wyświetlenie formularza z błędami i zapis poprawnych danych w bazie zapytaniem przygotowanym. Ten materiał rozwija dział o formularzach w kursie PHP w TablicaPro, gdzie znajdziesz prezentacje, ćwiczenia i testy do prowadzenia lekcji.
Źródła techniczne: filter_var w podręczniku PHP oraz filtry walidacyjne. Zobacz też lekcję o htmlspecialchars.
Poprowadź kolejne lekcje PHP
Pełny kurs: prezentacje, ćwiczenia i testy do pracy z klasą.
Kup dostęp do kursu PHP →