filter_var($value, FILTER_VALIDATE_EMAIL) restituisce il valore quando è un indirizzo email valido e false quando non lo è. Cambia il filtro per verificare altri formati: FILTER_VALIDATE_INT, FILTER_VALIDATE_FLOAT, FILTER_VALIDATE_URL, FILTER_VALIDATE_BOOL, FILTER_VALIDATE_IP. Confronta sempre il risultato con === false.
Due risultati sorprendono. ada@example viene rifiutato perché il dominio non ha un punto, e ' ada@example.com' viene rifiutato per lo spazio iniziale, quindi applica trim() all'input prima di validarlo.
Validare un'email da un form
Lo stesso controllo dietro un form. Eseguilo, scrivi un indirizzo e premi Check; il blocco viene eseguito di nuovo con il tuo input in $_POST.
FILTER_VALIDATE_EMAIL controlla solo il formato. nobody@example.com passa, e passerebbe anche un indirizzo con un errore di battitura nel dominio. I caratteri non ASCII vengono rifiutati: adä@example.com passa solo con FILTER_FLAG_EMAIL_UNICODE, che li consente prima della @, e un dominio come exämple.com fallisce anche con il flag a meno che tu non lo converta prima nella sua forma xn--. L'unico modo per sapere se un indirizzo funziona è inviargli un link di conferma.
Validare un intero con min_range e max_range
FILTER_VALIDATE_INT trasforma una stringa valida in un int e rifiuta tutto il resto. L'array di opzioni aggiunge un intervallo e un default:
Gli spazi intorno e un + iniziale sono accettati, uno zero iniziale ('042') no, e il risultato per '42' è l'intero 42, non la stringa. Fuori intervallo dà false; con un'opzione default ottieni il default invece di false, comodo per cose come ?page= (vedi _POST). Aggiungi FILTER_FLAG_ALLOW_HEX o FILTER_FLAG_ALLOW_OCTAL per accettare 0x1A o 0755.
La trappola di 0 e false
Un '0' valido restituisce l'intero 0, e 0 è falsy. Un semplice if lo tratta come un fallimento:
Lo stesso vale per FILTER_VALIDATE_FLOAT ('0.0') e per FILTER_VALIDATE_BOOL, dove false è una risposta valida. È a questo che serve FILTER_NULL_ON_FAILURE.
Booleani, float, URL e indirizzi IP
FILTER_VALIDATE_BOOL è il nome di PHP 8; FILTER_VALIDATE_BOOLEAN è lo stesso filtro. Senza FILTER_NULL_ON_FAILURE, 'maybe' restituirebbe false, indistinguibile da 'off'.
Un URL valido non è un link sicuro
FILTER_VALIDATE_URL verifica che la stringa abbia la forma di un URL, con qualsiasi schema. Questo include schemi che non vuoi mai in un href:
javascript://comment%0Aalert(1) supera FILTER_VALIDATE_URL, e un browser lo esegue come JavaScript quando il link viene cliccato, perché %0A chiude il //comment. Verifica lo schema con parse_url() prima di stampare in una pagina l'URL di un utente. Puoi anche richiedere delle parti con FILTER_FLAG_PATH_REQUIRED e FILTER_FLAG_QUERY_REQUIRED.
Filtri di sanitizzazione
I filtri di sanitizzazione rimuovono caratteri invece di dire sì o no. Sono utili per normalizzare l'input, non per renderlo sicuro da stampare:
Guarda la prima riga: Order #12-345 (x2) diventa 12-3452, un numero che non c'è mai stato nell'input, e la terza riga è un indirizzo che nessuno ha scritto. Se sanitizzi, valida poi il risultato. Per tutto ciò che stampi nell'HTML, lo strumento giusto è htmlspecialchars() al momento dell'output (FILTER_SANITIZE_FULL_SPECIAL_CHARS applica lo stesso escape). FILTER_SANITIZE_STRING è deprecato da PHP 8.1; vedi htmlspecialchars per cosa usare al suo posto.
Validare un intero form con filter_var_array
filter_var_array() applica un filtro per chiave e restituisce un array con ogni chiave che hai chiesto: il valore filtrato, false quando la validazione è fallita, oppure null quando la chiave mancava.
role è sparito: le chiavi che non hai elencato vengono scartate, il che impedisce a un visitatore di aggiungere role=admin a un form e farlo salvare. country è null perché non è stato inviato. Su un server web, filter_input_array(INPUT_POST, $rules) fa la stessa cosa leggendo direttamente dalla richiesta.
Domande frequenti
Come valido un indirizzo email in PHP?
Usa filter_var($email, FILTER_VALIDATE_EMAIL), che restituisce la stringa dell'email se è valida e false altrimenti: if (filter_var($email, FILTER_VALIDATE_EMAIL) === false) { /* invalid */ }. Controlla solo il formato; per sapere se l'indirizzo esiste, invia un'email di conferma.
Come verifico se una stringa è un intero in PHP?
filter_var($s, FILTER_VALIDATE_INT) restituisce l'int per "42", "-7" e " 42 ", e false per "4.2", "42abc" o "042". Confronta con !== false, perché un "0" valido restituisce 0, che è falsy.
Perché filter_var restituisce false per 0?
Non lo fa: filter_var('0', FILTER_VALIDATE_INT) restituisce l'intero 0. Il bug è nel controllo, if (filter_var(...)), che tratta 0 come false. Scrivi if (filter_var($v, FILTER_VALIDATE_INT) !== false).
Cosa ha sostituito FILTER_SANITIZE_STRING in PHP 8.1?
Nulla direttamente; è stato deprecato perché il suo nome prometteva una sicurezza che non dava. Valida l'input che ti aspetti, salvalo così com'è e applica l'escape quando lo stampi con htmlspecialchars(). Se ti serve rimuovere i tag, usa strip_tags().
Qual è la differenza tra filter_var e filter_input?
filter_var() filtra qualsiasi valore che gli passi. filter_input(INPUT_GET, 'id', FILTER_VALIDATE_INT) legge direttamente dalla richiesta originale, quindi restituisce null quando il parametro manca e ignora le modifiche che il tuo codice ha fatto a $_GET. Entrambi accettano gli stessi filtri e opzioni.