W3docs

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:

  1. L'utente compila i campi e fa clic su Invia.
  2. Il browser pacchettizza i valori dei campi in base al method del form e li invia all'URL indicato nell'action del form.
  3. PHP sul server riceve i valori in un array superglobale$_POST o $_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).
  • methodpost o get (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 datiCorpo della richiesta HTTPAggiunto all'URL come query string
Array PHP$_POST$_GET
Visibile nell'URLNoSì (?name=Ann&email=...)
Salvabile come segnalibro / condivisibileNo
Adatto perPassword, tutto ciò che modifica datiFiltri 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);
// &lt;script&gt;alert(&quot;xss&quot;)&lt;/script&gt;

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

Esercitazione

Pratica
Cosa fa $_POST in PHP?
Cosa fa $_POST in PHP?
Was this page helpful?