← Lekcje
PHP · lekcja 17

Formularze 2/2: sprawdzamy, czy pole nie jest puste

Dzisiaj:

  1. Funkcja empty() sprawdza, czy pole formularza zostało wypełnione
  2. Funkcja filter_var() z FILTER_VALIDATE_EMAIL sprawdza, czy adres e-mail ma poprawną formę
  3. Gdy dane są niepoprawne, pokazujemy komunikat błędu zamiast przetwarzać je dalej
  4. Ćwiczenie: rozbudowujemy contact.php o te dwa sprawdzenia
Rozgrzewka · 3 minuty

Rozgrzewka: formularz i $_POST

  1. Czym różni się method="get" od method="post"?
  2. Skąd biorą się klucze w tablicy $_POST?
  3. Dlaczego hasła nie wysyła się metodą GET?
Część 1 · Czy pole jest puste?

Funkcja empty()

Na poprzedniej lekcji contact.php ufał każdemu, kto wyśle formularz - nawet pustemu. Funkcja empty() sprawdza, czy zmienna nie istnieje albo ma wartość traktowaną jak „pusta” (pusty tekst, 0, null). Zwraca true albo false i, co ważne, nie zgłasza ostrzeżenia, gdy zmienna w ogóle nie istnieje.

$_POST["userName"] wartość z formularza empty(...)? sprawdzenie tak, puste komunikat błędu „Pole «Imię» jest wymagane.” nie, wypełnione dalej: kolejne sprawdzenie
PHP Manual: „Determine whether a variable is considered to be empty. […] empty() does not generate a warning if the variable does not exist.” · php.net/manual/en/function.empty.php
Część 2 · Sprawdzanie adresu e-mail

filter_var() z FILTER_VALIDATE_EMAIL

empty() sprawdza tylko, czy coś w polu w ogóle jest - nie sprawdza, czy to, co jest, ma sensowną formę. Do adresu e-mail służy filter_var(): dostaje wartość i filtr FILTER_VALIDATE_EMAIL. Gdy adres ma poprawną formę, zwraca ten adres. Gdy forma jest zła, zwraca false.

"jan@example.com" filter_var(..., FILTER_VALIDATE_EMAIL) zwraca "jan@example.com" "janek-at-example" filter_var(..., FILTER_VALIDATE_EMAIL) zwraca false

Ciekawostka z PHP Manual: filter_var() z FILTER_VALIDATE_EMAIL tylko sprawdza dane, nigdy ich nie zmienia. PHP ma osobno filtry sanitujące, np. FILTER_SANITIZE_EMAIL - on usuwa z adresu niedozwolone znaki, ale nie sprawdza, czy wynik jest poprawnym e-mailem. To dwie różne operacje w tym samym rozszerzeniu filter.

PHP Manual: „Filters a variable with a specified filter.” Zwraca dane po filtrowaniu przy powodzeniu, false przy niepowodzeniu · php.net/manual/en/function.filter-var.php · ciekawostka: PHP Manual, „A validation filter is used to check if the data meets certain criteria. […] it will never alter the input data” i „Sanitization […] may alter the input data by adding or removing characters. […] the sanitized data is not validated to check if it is a valid email address” · php.net/manual/en/book.filter.php
Część 3 · Cała ścieżka

Formularz → sprawdzenie → odpowiedź

Oba sprawdzenia łączymy w jednym pliku contact.php: najpierw empty() dla imienia, potem filter_var() dla e-maila. Dopiero gdy oba przejdą, skrypt pokazuje podziękowanie - w każdym innym przypadku pokazuje komunikat błędu i kończy.

contact.html formularz contact.php empty($_POST["userName"]) filter_var($_POST["userEmail"], …) błąd komunikat, dalej nic się nie dzieje sukces: „Dziękujemy, Jan! …”
PHP Manual: function.empty.php, function.filter-var.php
Część 4 · Kod na żywo

Rozbudowujemy contact.php

// contact.html: dochodzi trzecie pole
<input type="email" name="userEmail">
// contact.php
if (empty($_POST["userName"])) {
    echo "Pole \"Imię\" jest wymagane.";
} else {
    $email = filter_var($_POST["userEmail"], FILTER_VALIDATE_EMAIL);
    if ($email === false) {
        echo "Podaj poprawny adres e-mail.";
    } else {
        echo "Dziękujemy, " . $_POST["userName"] . "! Odpiszemy na " . $email;
    }
}
// puste userName:      Pole "Imię" jest wymagane.
// zły e-mail:           Podaj poprawny adres e-mail.
// poprawne dane:        Dziękujemy, Jan! Odpiszemy na jan@example.com
PHP Manual: function.empty.php, function.filter-var.php
Egzamin INF.03

Tak pytają na egzaminie

1. if (empty($_POST["name"])) { $nameErr = "Name is required"; } Przedstawiony fragment kodu PHP służy do obsługi

  1. sesji.
  2. ciasteczek.
  3. formularza.
  4. bazy danych.

2. Witryna internetowa wysyła dane poufne za pomocą formularza do kodu PHP. Która metoda wysłania jest najbardziej bezpieczna?

  1. Metoda GET, za pomocą protokołu HTTP
  2. Metoda POST, za pomocą protokołu HTTP
  3. Metoda GET, za pomocą protokołu HTTPS
  4. Metoda POST, za pomocą protokołu HTTPS
CKE, EE.09, czerwiec 2021, zadanie 9 · CKE, EE.09, styczeń 2020, zadanie 24
Ćwiczenie przy komputerze · 16 minut

Ćwiczenie: sprawdzanie pól

  1. W contact.html dodaj trzecie pole: <input type="email" name="userEmail">.
  2. W contact.php dodaj empty() dla każdego z trzech pól (userName, userMessage, userEmail) - każde puste pole ma dać osobny komunikat błędu.
  3. Dodaj sprawdzenie filter_var($_POST["userEmail"], FILTER_VALIDATE_EMAIL) - gdy adres jest niepoprawny, pokaż komunikat błędu zamiast dziękowania.
  4. Sprawdź trzy przypadki w przeglądarce: puste pole, zły adres e-mail (np. bez @), poprawne dane.
  5. Zapisz zmiany w repozytorium: commit „Dodaje sprawdzanie pól formularza” i push.

Ma się pojawić: przy pustym polu albo złym e-mailu - komunikat błędu; przy poprawnych danych - „Dziękujemy, [imię]! Odpiszemy na [e-mail]”.

Cały plik
// contact.php
if (empty($_POST["userName"])) {
    echo "Pole \"Imię\" jest wymagane.";
} elseif (empty($_POST["userMessage"])) {
    echo "Pole \"Wiadomość\" jest wymagane.";
} else {
    $email = filter_var($_POST["userEmail"], FILTER_VALIDATE_EMAIL);
    if ($email === false) {
        echo "Podaj poprawny adres e-mail.";
    } else {
        echo "Dziękujemy, " . $_POST["userName"] . "! Odpiszemy na " . $email;
    }
}
// przy userName="", userEmail=jan@example.com: Pole "Imię" jest wymagane.
// przy userName=Jan, userEmail=janek-at-example:  Podaj poprawny adres e-mail.
// przy userName=Jan, userEmail=jan@example.com:   Dziękujemy, Jan! Odpiszemy na jan@example.com
Na koniec

Sprawdź się

  1. Co zwraca empty($field), gdy zmienna $field w ogóle nie istnieje?
  2. Co zwraca filter_var($e, FILTER_VALIDATE_EMAIL), gdy $e ma niepoprawną formę?
  3. Dlaczego sprawdzenie empty() musi być przed dalszym przetwarzaniem danych, nie po nim?

To była druga i ostatnia lekcja tematu formularzy.

Poza szkołą

A jak to wygląda w produkcji?

Na lekcjiW produkcjiStatus
empty() i filter_var() wywołane ręcznie, jedno po drugimFrameworki (np. Laravel) mają gotowe klasy walidacji z regułami typu required, email, deklarowanymi w jednym miejscu zamiast ciągu if.zastępowane (frameworkiem)
Komunikat błędu wypisany przez echo jako sam tekstFormularz po błędzie zwykle wraca z podświetlonym polem i komunikatem obok niego, z zachowaniem tego, co użytkownik już wpisał.nadal w użyciu (rozbudowane o UX)
Sprawdzana tylko forma adresu e-mailPoprawna forma nie znaczy, że skrzynka istnieje - do tego służy osobno wysłany e-mail z linkiem potwierdzającym.nadal w użyciu (jako dodatkowy krok)
PHP Manual: function.empty.php, function.filter-var.php