W3docs

Validazione dei Form PHP

La validazione dei form è essenziale nello sviluppo web: garantisce che i dati inseriti dagli utenti siano corretti e completi prima dell'elaborazione con PHP.

La validazione dei form è il processo di verifica che i dati inviati dall'utente tramite un form HTML siano presenti, correttamente formattati e sicuri da utilizzare prima che lo script li elabori. In PHP, la validazione viene eseguita sul server dopo l'invio del form, quindi non può essere aggirata disabilitando JavaScript o inviando una richiesta direttamente.

Questo capitolo illustra l'intero flusso di validazione: perché la validazione lato server è importante, la differenza tra sanitizzare e validare, le funzioni PHP da utilizzare e un esempio completo e sicuro che puoi adattare. Se non hai familiarità con la ricezione dell'input dei form, leggi prima Gestione dei Form PHP.

Perché la Validazione Lato Server è Importante

La validazione lato client (HTML5 required, type="email", JavaScript) migliora l'esperienza utente rilevando gli errori immediatamente — ma è solo una comodità. Un utente determinato o malintenzionato può disabilitare JavaScript o inviare una richiesta HTTP costruita ad hoc che bypassa completamente il browser. Il server è l'unico posto in cui la validazione può essere considerata attendibile. La validazione PHP lato server ti permette di:

  • Garantire che i campi obbligatori siano effettivamente presenti e non vuoti.
  • Verificare che i valori corrispondano al formato atteso (un'email reale, un numero nell'intervallo corretto).
  • Neutralizzare l'input pericoloso prima che raggiunga un database o una pagina HTML, prevenendo l'SQL injection e il cross-site scripting (XSS).

Considera ogni valore in $_POST, $_GET e $_REQUEST come non attendibile finché non lo hai verificato. Questi array provengono dai superglobals di PHP.

Sanitizzare vs. Validare

Questi due termini vengono spesso confusi, ma svolgono compiti diversi:

  • Sanitizzare pulisce un valore — rimuove o fa l'escape dei caratteri indesiderati. trim() elimina gli spazi bianchi circostanti; htmlspecialchars() converte <, >, & e le virgolette in entità HTML in modo che vengano visualizzate come testo invece di essere eseguite.
  • Validare verifica un valore rispetto a una regola e indica se passa o fallisce — non modifica il valore. filter_var($email, FILTER_VALIDATE_EMAIL) restituisce l'email se sembra valida, oppure false in caso contrario.

Un flusso tipico è: sanitizzare prima (rimuovere gli spazi bianchi), poi validare, e infine fare l'escape in output (quando si stampa nell'HTML). Per una copertura più approfondita del sistema di filtraggio di PHP, vedi PHP Filters e filter_var().

Passi della Validazione

Una routine di validazione lato server solitamente segue gli stessi quattro passi:

  1. Costruire il form HTML e puntare il suo action allo script PHP.
  2. Rilevare un'invio POST con $_SERVER["REQUEST_METHOD"].
  3. Per ogni campo: leggere il valore, sanitizzarlo, poi validarlo — raccogliendo tutti i messaggi di errore.
  4. Se ogni campo ha superato la verifica, elaborare i dati; altrimenti visualizzare nuovamente il form con i messaggi di errore e i valori già inseriti dall'utente.

Funzioni PHP Utili per la Validazione

FunzioneScopo
trim()Rimuove gli spazi bianchi dall'inizio e dalla fine di una stringa.
empty()Verifica se un valore è assente o una stringa vuota.
filter_var()Valida o sanitizza usando un filtro integrato (es. FILTER_VALIDATE_EMAIL, FILTER_VALIDATE_INT).
is_numeric()Restituisce true se il valore è un numero o una stringa numerica.
htmlspecialchars()Fa l'escape dei caratteri speciali HTML per prevenire XSS in output.
preg_match()Valida rispetto a un pattern di espressione regolare personalizzato.

Un Esempio Minimo

Prima del completo esempio con database riportato di seguito, ecco la validazione più semplice che cattura il pattern principale — sanitizzare, poi validare, poi raccogliere gli errori:

<?php
$email = trim($_POST["email"] ?? "");
$errors = [];

if ($email === "") {
    $errors["email"] = "Please enter your email.";
} elseif (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
    $errors["email"] = "Please enter a valid email address.";
}

if (empty($errors)) {
    echo "Valid email: " . htmlspecialchars($email);
} else {
    echo $errors["email"];
}
?>

Se $_POST["email"] è " [email protected] ", gli spazi circostanti vengono rimossi, il valore viene validato e lo script stampa Valid email: [email protected]. Un valore come "not-an-email" produce Please enter a valid email address.

Esempio Completo: Validare e Salvare un Form

L'esempio seguente valida un nome, un'email, un genere e un commento, quindi inserisce la riga usando una prepared statement — l'approccio con le prepared statement (con mysqli) è ciò che protegge dall'SQL injection, perché l'input dell'utente viene inviato separatamente dal testo SQL e non viene mai interpretato come codice.

Aggiorna le credenziali del database e assicurati che il tuo database contenga una tabella users con le colonne name, email, gender e comment prima di eseguire questo esempio.

<?php
// Database connection setup
$link = mysqli_connect("localhost", "username", "password", "database");
if (!$link) {
    die("Connection failed: " . mysqli_connect_error());
}

// Define variables and initialize with empty values
$name = $email = $gender = $comment = $website = "";
$name_err = $email_err = $gender_err = $comment_err = "";
 
// Processing form data when form is submitted
if($_SERVER["REQUEST_METHOD"] == "POST"){
    // Validate name
    if(empty(trim($_POST["name"] ?? ""))){
        $name_err = "Please enter your name.";
    } else{
        $name = trim($_POST["name"]);
    }
    
    // Validate email
    if(empty(trim($_POST["email"] ?? ""))){
        $email_err = "Please enter your email.";
    } elseif(!filter_var(trim($_POST["email"] ?? ""), FILTER_VALIDATE_EMAIL)) {
        $email_err = "Please enter a valid email address.";
    } else{
        $email = trim($_POST["email"]);
    }
    
    // Validate gender
    if(!isset($_POST["gender"]) || empty($_POST["gender"])){
        $gender_err = "Please select your gender.";
    } else{
        $gender = $_POST["gender"];
    }
    
    // Validate comment
    if(empty(trim($_POST["comment"] ?? ""))){
        $comment_err = "Please enter your comment.";
    } else{
        $comment = trim($_POST["comment"]);
    }
    
    // Check input errors before inserting in database
    if(empty($name_err) && empty($email_err) && empty($gender_err) && empty($comment_err)){
        // Prepare an insert statement
        $sql = "INSERT INTO users (name, email, gender, comment) VALUES (?, ?, ?, ?)";
         
        if($stmt = mysqli_prepare($link, $sql)){
            // Bind variables to the prepared statement as parameters
            mysqli_stmt_bind_param($stmt, "ssss", $param_name, $param_email, $param_gender, $param_comment);
            
            // Set parameters
            $param_name = $name;
            $param_email = $email;
            $param_gender = $gender;
            $param_comment = $comment;
            
            // Attempt to execute the prepared statement
            if(mysqli_stmt_execute($stmt)){
                // Records created successfully. Redirect to landing page
                header("location: index.php");
                exit();
            } else{
                echo "Something went wrong. Please try again later.";
            }
        }
         
        // Close statement
        mysqli_stmt_close($stmt);
    }
}

// Close connection
mysqli_close($link);
?>
<!DOCTYPE html>
<html>
<head><title>PHP Form Validation</title></head>
<body>
<form method="post" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]); ?>">
    Name: <input type="text" name="name" value="<?php echo htmlspecialchars($name); ?>">
    <span class="error"><?php echo $name_err; ?></span><br><br>
    Email: <input type="text" name="email" value="<?php echo htmlspecialchars($email); ?>">
    <span class="error"><?php echo $email_err; ?></span><br><br>
    Gender:
    <input type="radio" name="gender" value="female"> Female
    <input type="radio" name="gender" value="male"> Male
    <span class="error"><?php echo $gender_err; ?></span><br><br>
    Comment: <textarea name="comment"><?php echo htmlspecialchars($comment); ?></textarea>
    <span class="error"><?php echo $comment_err; ?></span><br><br>
    <input type="submit" value="Submit">
</form>
</body>
</html>

Mostrare gli Errori e Mantenere l'Input dell'Utente

Nota tre dettagli nell'esempio che migliorano la UX del form:

  • Ogni variabile di errore ($name_err, $email_err, …) viene stampata in uno <span class="error"> accanto al suo campo, così l'utente sa esattamente quale input correggere.
  • L'action del form stampa htmlspecialchars($_SERVER["PHP_SELF"]). Senza l'escape, PHP_SELF può essere sfruttato per iniettare script tramite l'URL, quindi l'escape è una misura di sicurezza, non solo di formattazione.
  • Ogni valore visualizzato nuovamente nel form viene passato attraverso htmlspecialchars(). Questo sia previene XSS sia permette all'utente di mantenere ciò che ha già digitato invece di reinserire tutto dopo un campo non valido.

Errori Comuni

  • empty() tratta "0" come vuoto. Un campo il cui valore è la stringa "0" fallirà un controllo empty(). Per i campi in cui 0 è valido, confronta esplicitamente: if ($value === "").
  • Valida prima di fidarti del tipo. I valori $_POST sono sempre stringhe. Usa filter_var($n, FILTER_VALIDATE_INT) o is_numeric() invece di assumere che sia arrivato un numero.
  • Fai l'escape in output, non in storage. Salva il valore grezzo (validato) nel database e applica htmlspecialchars() solo quando lo stampi nell'HTML. Fare l'escape prima dello storage corrompe i dati per gli usi non HTML.
  • Usa l'operatore null-coalescing. $_POST["x"] ?? "" evita gli avvisi "Undefined array key" quando un campo è assente.

Validare Altri Tipi di Campo

Lo stesso pattern si estende a qualsiasi campo — cambia solo la regola di validazione:

<?php
// Age: an integer between 18 and 120
$age = filter_var($_POST["age"] ?? "", FILTER_VALIDATE_INT, [
    "options" => ["min_range" => 18, "max_range" => 120],
]);
if ($age === false) {
    echo "Please enter an age between 18 and 120.";
}

// Username: 3-16 letters, digits, or underscores
$username = trim($_POST["username"] ?? "");
if (!preg_match('/^[A-Za-z0-9_]{3,16}$/', $username)) {
    echo "Username must be 3-16 letters, digits, or underscores.";
}
?>

Per le regole specifiche su URL e email, vedi PHP Form URL & E-mail; per rendere i campi obbligatori, vedi PHP Form Required Fields; e per vedere tutti gli elementi assemblati, vedi PHP Complete Form.

Conclusione

La validazione lato server in PHP è ciò che rende un form affidabile: conferma che i dati siano presenti e correttamente formattati, e — abbinata a htmlspecialchars() in output e alle prepared statement per lo storage — blocca XSS e SQL injection. La ricetta di base è sempre la stessa: sanitizzare, validare, raccogliere gli errori e visualizzare nuovamente il form con messaggi utili quando qualcosa non va. Padroneggia quel ciclo e potrai validare qualsiasi campo semplicemente sostituendo la regola.

Esercitazione

Pratica
Quali sono alcuni elementi chiave nella validazione dei form PHP?
Quali sono alcuni elementi chiave nella validazione dei form PHP?
Was this page helpful?