Elaborazione dei form PHP: guida completa
Scopri come PHP gestisce i form web: lettura dei dati, validazione server-side, protezione da XSS e SQL injection con esempi pratici.
La gestione dei form è uno dei compiti più comuni in qualsiasi applicazione web: una pagina di registrazione, un modulo di contatto, una casella di ricerca o un flusso di pagamento inviano tutti l'input dell'utente al server, dove PHP lo legge, lo verifica e agisce di conseguenza. Questa guida percorre l'intero ciclo — dal form HTML nel browser al PHP che riceve, valida e riutilizza in modo sicuro i dati inviati.
Al termine comprenderai come funzionano $_POST e $_GET, come validare l'input lato server, come mantenere il form "sticky" dopo un errore e come evitare i due classici problemi di sicurezza (XSS e SQL injection).
Come funziona l'invio di un form
L'invio di un form è una singola richiesta HTTP dal browser al server:
- L'utente compila i campi e fa clic su Invia.
- Il browser pacchettizza i valori dei campi in base al
methoddel form e li invia all'URL indicato nell'actiondel form. - PHP sul server riceve i valori in un array superglobale —
$_POSTo$_GET— e il tuo script li elabora.
Poiché i dati provengono dal browser dell'utente, non puoi mai fidarti di essi. Chiunque può modificare i valori dei campi, rimuovere campi o inviare la richiesta senza utilizzare il tuo form. La validazione lato server non è quindi opzionale — gli attributi required e type="email" lato client sono solo una comodità.
Creare un form HTML
Ogni form inizia in HTML. Il form contiene campi di input — caselle di testo, campi email, pulsanti radio, checkbox — e un pulsante di invio. Due attributi governano tutto:
action— l'URL che riceve i dati (omettilo per rinviare alla stessa pagina).method—postoget(vedi il confronto di seguito).
<form action="form_processing.php" method="post">
<p>
<label for="name">Name:</label>
<input type="text" id="name" name="name" />
</p>
<p>
<label for="email">Email:</label>
<input type="email" id="email" name="email" />
</p>
<input type="submit" value="Submit" />
</form>L'attributo name di ogni input è la chiave che leggi sul server: name="email" diventa $_POST['email']. Un input senza name non viene mai inviato. Abbina sempre ogni campo a un <label> per l'accessibilità.
POST vs. GET
L'attributo method decide come viaggiano i dati e quale array li riceve.
method="post" | method="get" | |
|---|---|---|
| Posizione dei dati | Corpo della richiesta HTTP | Aggiunto all'URL come query string |
| Array PHP | $_POST | $_GET |
| Visibile nell'URL | No | Sì (?name=Ann&email=...) |
| Salvabile come segnalibro / condivisibile | No | Sì |
| Adatto per | Password, tutto ciò che modifica dati | Filtri di ricerca, paginazione — richieste in sola lettura |
Usa POST per tutto ciò che crea, aggiorna o elimina dati, o che contiene valori sensibili. Usa GET per ricerche e filtri che vuoi che gli utenti possano aggiungere ai preferiti. Entrambi arrivano nel superglobale corrispondente; il resto di questa guida usa POST.
Leggere i dati inviati
Quando il form viene inviato, PHP riempie $_POST con i nomi dei campi come chiavi e il testo inviato come valori. Leggi ogni campo, ma proteggiti dalle chiavi mancanti con l'operatore null coalescing ?? in modo che un campo mancante restituisca una stringa vuota invece di un avviso:
$name = $_POST['name'] ?? '';
$email = $_POST['email'] ?? '';Controlla $_SERVER['REQUEST_METHOD'] affinché il codice di elaborazione venga eseguito solo su un invio effettivo, non quando la pagina viene aperta per la prima volta:
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$name = $_POST['name'] ?? '';
$email = $_POST['email'] ?? '';
// ...validate and use the values
}Validare l'input
La validazione risponde a una domanda: questo valore è accettabile? Raccogli ogni problema in un array $errors in modo da poter mostrare all'utente tutti gli errori contemporaneamente, invece di fermarti al primo. Usa filter_var() con FILTER_VALIDATE_EMAIL per verificare correttamente il formato dell'email:
$errors = [];
if (trim($name) === '') {
$errors[] = "Name is required";
}
if (trim($email) === '') {
$errors[] = "Email is required";
} elseif (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
$errors[] = "Invalid email format";
}
if (!empty($errors)) {
foreach ($errors as $error) {
echo htmlspecialchars($error) . "<br>";
}
}Usiamo trim() affinché un campo contenente solo spazi venga comunque considerato vuoto, poi filter_var() per confermare che l'email assomigli a [email protected]. Se $errors non è vuoto, i messaggi vengono stampati; altrimenti i dati sono puliti e pronti all'uso. Per una copertura più approfondita dei campi obbligatori e delle regole per email/URL, consulta validazione dei form PHP e validazione dei campi obbligatori.
Escape dell'output: prevenire XSS
Nota la chiamata a htmlspecialchars() sopra. Ogni volta che mostri un valore proveniente dall'utente, devi eseguire l'escape, altrimenti un attaccante può inviare tag <script> che vengono eseguiti nei browser degli altri visitatori — un attacco cross-site scripting (XSS). htmlspecialchars() converte <, >, & e le virgolette in entità HTML innocue:
$dangerous = '<script>alert("xss")</script>';
echo htmlspecialchars($dangerous);
// <script>alert("xss")</script>Il browser ora mostra il testo letteralmente invece di eseguirlo. Esegui sempre l'escape in output, ogni volta.
Mantenere il form sticky
Se la validazione fallisce, visualizza nuovamente il form con i valori dell'utente ancora compilati — dover riscrivere tutto è frustrante. Rimanda ogni valore nel suo attributo value, con l'escape applicato:
<input
type="text"
name="name"
value="<?php echo htmlspecialchars($name ?? ''); ?>"
/>Poiché la stessa pagina sia mostra il form sia lo elabora, imposta action="" (rinvia a se stessa) e il campo si ripopola automaticamente dopo un invio fallito.
Tutto insieme
Ecco una singola pagina auto-elaborante che mostra il form, valida su POST, visualizza gli errori, mantiene il form sticky e conferma il successo — il pattern che seguono la maggior parte dei form di contatto reali:
<?php
$name = $email = '';
$errors = [];
$success = false;
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$name = trim($_POST['name'] ?? '');
$email = trim($_POST['email'] ?? '');
if ($name === '') {
$errors[] = 'Name is required';
}
if ($email === '') {
$errors[] = 'Email is required';
} elseif (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
$errors[] = 'Invalid email format';
}
if (!$errors) {
$success = true; // here you would save to a database or send an email
}
}
?>
<?php if ($success): ?>
<p>Thanks, <?php echo htmlspecialchars($name); ?>!</p>
<?php else: ?>
<?php foreach ($errors as $e): ?>
<p style="color:red"><?php echo htmlspecialchars($e); ?></p>
<?php endforeach; ?>
<form action="" method="post">
Name:
<input type="text" name="name"
value="<?php echo htmlspecialchars($name); ?>"><br>
Email:
<input type="email" name="email"
value="<?php echo htmlspecialchars($email); ?>"><br>
<input type="submit" value="Submit">
</form>
<?php endif; ?>Memorizzare i dati in modo sicuro: prevenire l'SQL injection
Una volta che i dati sono validi, spesso li si salva in un database. Non inserire mai direttamente l'input dell'utente in una stringa SQL — questo apre la porta all'SQL injection. Usa una prepared statement affinché il database tratti i valori come dati, mai come comandi:
$mysqli = new mysqli('localhost', 'user', 'pass', 'app');
$stmt = $mysqli->prepare(
'INSERT INTO contacts (name, email) VALUES (?, ?)'
);
$stmt->bind_param('ss', $name, $email);
$stmt->execute();I segnaposto ? e bind_param() mantengono i valori separati dalla query, quindi un input come '; DROP TABLE contacts; -- viene memorizzato come testo innocuo invece di essere eseguito.
Checklist di sicurezza
Uno script di elaborazione dei form sicuro segue una routine breve e ripetibile:
- Valida ogni campo lato server — non fare mai affidamento solo sui controlli del browser.
- Esegui l'escape in output con
htmlspecialchars()per bloccare XSS. - Usa le prepared statement per ogni query al database per bloccare l'SQL injection.
- Hasha le password con
password_hash()prima di memorizzarle — non memorizzare mai testo in chiaro. - Aggiungi un token CSRF ai form che modificano lo stato affinché le richieste non possano essere falsificate da altri siti.
- Aggiungi un CAPTCHA ai form pubblici per ridurre le submission automatiche di spam.
Capitoli correlati
- Gestione dei form PHP — le basi per ricevere i dati del form.
- PHP $_POST — il superglobale in dettaglio.
- Validazione dei form PHP — pattern di validazione completi.
- Superglobali PHP —
$_POST,$_GET,$_SERVERe altro.