filter_var($value, FILTER_VALIDATE_EMAIL) zwraca wartość, gdy jest poprawnym adresem e-mail, i false, gdy nie jest. Zmień filtr, aby sprawdzać inne formaty: FILTER_VALIDATE_INT, FILTER_VALIDATE_FLOAT, FILTER_VALIDATE_URL, FILTER_VALIDATE_BOOL, FILTER_VALIDATE_IP. Zawsze porównuj wynik z === false.
Dwa wyniki zaskakują. ada@example jest odrzucany, bo domena nie ma kropki, a ' ada@example.com' jest odrzucany przez spację na początku, więc przed walidacją przepuść dane przez trim().
Walidacja e-maila z formularza
To samo sprawdzenie w formularzu. Uruchom, wpisz adres i naciśnij Check; blok uruchomi się ponownie z twoimi danymi w $_POST.
FILTER_VALIDATE_EMAIL sprawdza tylko format. nobody@example.com przechodzi, tak samo jak adres z literówką w domenie. Znaki spoza ASCII są odrzucane: adä@example.com przechodzi tylko z FILTER_FLAG_EMAIL_UNICODE, które dopuszcza je przed @, a domena taka jak exämple.com nie przechodzi nawet z flagą, chyba że najpierw zamienisz ją na postać xn--. Jedyny sposób, by wiedzieć, że adres działa, to wysłać na niego link z potwierdzeniem.
Walidacja liczby całkowitej z min_range i max_range
FILTER_VALIDATE_INT zamienia poprawny string na int i odrzuca wszystko inne. Tablica opcji dodaje zakres i wartość domyślną:
Białe znaki wokół i początkowy + są akceptowane, początkowe zero ('042') nie, a wynik dla '42' to liczba całkowita 42, a nie string. Poza zakresem dostajesz false; z opcją default dostajesz wartość domyślną zamiast false, co przydaje się przy rzeczach takich jak ?page= (zobacz _POST). Dodaj FILTER_FLAG_ALLOW_HEX albo FILTER_FLAG_ALLOW_OCTAL, aby akceptować 0x1A lub 0755.
Pułapka 0 i false
Poprawne '0' zwraca liczbę całkowitą 0, a 0 jest traktowane jak fałsz. Zwykłe if uznaje to za porażkę:
To samo dotyczy FILTER_VALIDATE_FLOAT ('0.0') i FILTER_VALIDATE_BOOL, gdzie false to poprawna odpowiedź. Do tego służy FILTER_NULL_ON_FAILURE.
Wartości logiczne, liczby zmiennoprzecinkowe, URL i adresy IP
FILTER_VALIDATE_BOOL to nazwa z PHP 8; FILTER_VALIDATE_BOOLEAN to ten sam filtr. Bez FILTER_NULL_ON_FAILURE 'maybe' zwróciłoby false, nie do odróżnienia od 'off'.
Poprawny URL to nie bezpieczny link
FILTER_VALIDATE_URL sprawdza, czy string ma kształt adresu URL, z dowolnym schematem. Obejmuje to schematy, których nigdy nie chcesz w href:
javascript://comment%0Aalert(1) przechodzi FILTER_VALIDATE_URL, a przeglądarka wykonuje go jako JavaScript po kliknięciu linku, bo %0A kończy //comment. Zanim wypiszesz na stronie URL od użytkownika, sprawdź schemat przez parse_url(). Możesz też wymagać części przez FILTER_FLAG_PATH_REQUIRED i FILTER_FLAG_QUERY_REQUIRED.
Filtry oczyszczające
Filtry oczyszczające usuwają znaki, zamiast odpowiadać tak lub nie. Przydają się do normalizowania danych, a nie do czynienia ich bezpiecznymi do wypisania:
Spójrz na pierwszą linię: Order #12-345 (x2) staje się 12-3452, liczbą, której nigdy nie było w danych, a trzecia linia to adres, którego nikt nie wpisał. Jeśli oczyszczasz, potem zwaliduj wynik. Do wszystkiego, co wypisujesz do HTML, właściwym narzędziem jest htmlspecialchars() w chwili wypisywania (FILTER_SANITIZE_FULL_SPECIAL_CHARS escapuje tak samo). FILTER_SANITIZE_STRING jest przestarzały od PHP 8.1; co stosować zamiast niego, opisuje strona htmlspecialchars.
Walidacja całego formularza przez filter_var_array
filter_var_array() stosuje jeden filtr na klucz i zwraca tablicę z każdym kluczem, o który prosiłeś: przefiltrowaną wartością, false, gdy walidacja się nie powiodła, albo null, gdy klucza brakowało.
role zniknęło: klucze, których nie wymieniłeś, są odrzucane, co nie pozwala odwiedzającemu dodać role=admin do formularza i zapisać tego. country to null, bo nie zostało wysłane. Na serwerze WWW filter_input_array(INPUT_POST, $rules) robi to samo, czytając prosto z żądania.
Najczęściej zadawane pytania
Jak zwalidować adres e-mail w PHP?
Użyj filter_var($email, FILTER_VALIDATE_EMAIL), które zwraca string z e-mailem, jeśli jest poprawny, i false, jeśli nie: if (filter_var($email, FILTER_VALIDATE_EMAIL) === false) { /* invalid */ }. Sprawdza tylko format; aby wiedzieć, czy adres istnieje, wyślij e-mail z potwierdzeniem.
Jak sprawdzić, czy string jest liczbą całkowitą w PHP?
filter_var($s, FILTER_VALIDATE_INT) zwraca int dla "42", "-7" i " 42 ", a false dla "4.2", "42abc" czy "042". Porównuj przez !== false, bo poprawne "0" zwraca 0, które jest traktowane jak fałsz.
Dlaczego filter_var zwraca false dla 0?
Nie zwraca: filter_var('0', FILTER_VALIDATE_INT) zwraca liczbę całkowitą 0. Błąd leży w sprawdzeniu if (filter_var(...)), które traktuje 0 jak false. Napisz if (filter_var($v, FILTER_VALIDATE_INT) !== false).
Co zastąpiło FILTER_SANITIZE_STRING w PHP 8.1?
Nic bezpośrednio; oznaczono go jako przestarzały, bo jego nazwa obiecywała bezpieczeństwo, którego nie dawał. Waliduj oczekiwane dane, przechowuj je bez zmian i escapuj przy wypisywaniu przez htmlspecialchars(). Jeśli musisz usunąć znaczniki, użyj strip_tags().
Czym różni się filter_var od filter_input?
filter_var() filtruje dowolną przekazaną wartość. filter_input(INPUT_GET, 'id', FILTER_VALIDATE_INT) czyta prosto z pierwotnego żądania, więc zwraca null, gdy parametru brakuje, i ignoruje zmiany, które twój kod wprowadził w $_GET. Oba przyjmują te same filtry i opcje.