PHP AJAX Poll
Impara a costruire un sondaggio AJAX in PHP che registra i voti e mostra i risultati live senza ricaricare la pagina, usando fetch, JSON e MySQL.
Cos'è un AJAX Poll?
Un AJAX poll è un piccolo widget di voto che consente all'utente di scegliere un'opzione, invia il voto al server in background e mostra i risultati aggiornati — il tutto senza ricaricare la pagina. AJAX (Asynchronous JavaScript and XML) è la tecnica per scambiare dati con il server usando JavaScript dopo che la pagina è già stata caricata.
Questo capitolo costruisce un sondaggio completo: una tabella MySQL per memorizzare le opzioni e i loro conteggi di voto, uno script PHP che registra un voto e restituisce il totale corrente come JSON, e una piccola quantità di JavaScript che invia il voto e visualizza i risultati.
Se vuoi aggiornare continuamente i dati con un timer (un tabellone live, un dashboard di stato), gli stessi elementi di base si applicano — quel pattern si chiama polling, e lo trattiamo alla fine del capitolo.
Perché Usare AJAX per un Sondaggio?
- Nessun ricaricamento della pagina. L'utente rimane sulla pagina; cambia solo l'area del sondaggio. Questo dà una sensazione immediata e mantiene intatto il resto della pagina (posizione di scorrimento, video, input del modulo).
- Meno dati trasferiti. Invece di reinviare l'intero documento HTML, il server restituisce solo i conteggi dei voti come piccolo payload JSON.
- Risultati live. Poiché la risposta è dati, non markup, puoi ridisegnare immediatamente una barra dei risultati e aggiornarla anche su un timer per riflettere i voti degli altri utenti.
Passo 1 — Crea la Tabella del Database
Ogni opzione del sondaggio è una riga. Memorizziamo il testo dell'opzione e un contatore progressivo dei voti.
CREATE TABLE poll_options (
id INT AUTO_INCREMENT PRIMARY KEY,
option_text VARCHAR(100) NOT NULL,
votes INT NOT NULL DEFAULT 0
);
INSERT INTO poll_options (option_text) VALUES
('PHP'),
('JavaScript'),
('Python');Se non hai esperienza nella creazione di tabelle, consulta Crea una Tabella MySQL e Inserisci Dati.
Passo 2 — Costruisci il Modulo HTML
Il modulo elenca le opzioni come pulsanti radio e riserva un contenitore per i risultati.
<form id="pollForm">
<p>What is your favorite language?</p>
<label><input type="radio" name="option" value="1"> PHP</label>
<label><input type="radio" name="option" value="2"> JavaScript</label>
<label><input type="radio" name="option" value="3"> Python</label>
<button type="submit">Vote</button>
</form>
<div id="pollResults"></div>Il value di ogni pulsante radio è l'id dell'opzione nel database — è l'unica cosa che dobbiamo inviare al server.
Passo 3 — Scrivi il Gestore PHP
Lo script PHP svolge due compiti: registrare un voto (quando ne viene inviato uno) e restituire i risultati correnti come JSON. Usa sempre le prepared statement in modo che un valore proveniente dal browser non possa mai essere interpretato come SQL.
<?php
header('Content-Type: application/json');
$dsn = "mysql:host=localhost;dbname=your_database;charset=utf8mb4";
$options = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
];
try {
$pdo = new PDO($dsn, 'username', 'password', $options);
// If a vote was submitted, increment that option's counter.
if (isset($_POST['option'])) {
$optionId = (int) $_POST['option'];
$update = $pdo->prepare(
"UPDATE poll_options SET votes = votes + 1 WHERE id = :id"
);
$update->execute([':id' => $optionId]);
}
// Always return the current tally.
$rows = $pdo->query(
"SELECT id, option_text, votes FROM poll_options ORDER BY id"
)->fetchAll();
$total = array_sum(array_column($rows, 'votes'));
echo json_encode([
'status' => 'success',
'total' => $total,
'options' => $rows,
]);
} catch (PDOException $e) {
http_response_code(500);
echo json_encode(['status' => 'error', 'message' => 'Database error']);
}Il cast dell'id in ingresso con (int) e il suo binding con :id significa che il valore viene trattato rigorosamente come numero, non come parte della query. Per approfondire, leggi PHP Prepared Statements e json_encode().
Passo 4 — Invia il Voto con JavaScript
Intercettiamo l'evento submit del modulo, inviamo l'opzione selezionata con fetch(), poi visualizziamo una barra dei risultati dalla risposta JSON.
const form = document.getElementById('pollForm');
const resultsBox = document.getElementById('pollResults');
form.addEventListener('submit', function (event) {
event.preventDefault(); // Stop the normal page reload.
const selected = form.querySelector('input[name="option"]:checked');
if (!selected) return; // Nothing chosen yet.
const body = new URLSearchParams({ option: selected.value });
fetch('poll.php', { method: 'POST', body })
.then(response => response.json())
.then(showResults)
.catch(error => console.error('Vote failed:', error));
});
function showResults(data) {
if (data.status !== 'success') {
resultsBox.textContent = 'Could not load results.';
return;
}
resultsBox.innerHTML = data.options.map(opt => {
const percent = data.total
? Math.round((opt.votes / data.total) * 100)
: 0;
return `<div>${opt.option_text}: ${opt.votes} votes (${percent}%)</div>`;
}).join('');
}event.preventDefault() è ciò che impedisce al browser di eseguire un invio completo, che è proprio il punto dell'AJAX. La percentuale viene calcolata sul client dai conteggi restituiti dal server, quindi la barra corrisponde sempre ai dati più recenti.
Passo 5 — Mantieni i Risultati Live con il Polling
Finora i risultati si aggiornano solo quando questo utente vota. Per riflettere i voti degli altri utenti, interroga il server su un timer — richiedi il totale più recente ogni pochi secondi e ridisegna:
function refreshResults() {
fetch('poll.php') // GET, no vote — just read the tally.
.then(response => response.json())
.then(showResults)
.catch(error => console.error('Refresh failed:', error));
}
setInterval(refreshResults, 5000); // Every 5 seconds.Poiché il gestore PHP restituisce il totale a ogni richiesta (con voto o meno), un semplice GET è sufficiente per recuperare numeri aggiornati. Scegli l'intervallo con attenzione: un intervallo breve dà una sensazione più live ma genera più richieste. Per dati che devono essere veramente in tempo reale, WebSocket o Server-Sent Events sono più adatti del polling a intervallo fisso.
Errori Comuni
- Dimenticare
event.preventDefault(). Senza di esso il modulo ricarica la pagina e la chiamata AJAX viene annullata a metà. - Fidarsi dell'id dell'opzione. Effettua sempre il cast/validazione e usa una prepared statement; non concatenare mai
$_POSTin SQL. - Doppio conteggio. Questo esempio base permette a un browser di votare più volte. In produzione, limita per sessione, cookie o IP.
- Polling troppo aggressivo. Un intervallo di un secondo su una pagina molto trafficata può sovraccaricare il server; 3–10 secondi è di solito sufficiente.
Riepilogo
Un AJAX poll combina una tabella MySQL, un endpoint PHP che registra un voto e restituisce il totale come JSON, e JavaScript che invia con fetch() e visualizza i risultati — senza ricaricare la pagina. Aggiungi un setInterval di polling per mantenere i numeri aggiornati per tutti.
graph TD;
A(User Selects Option and Clicks Vote) --> B(JavaScript Sends POST with fetch);
B --> C(PHP Increments Vote with Prepared Statement);
C --> D(PHP Returns Tally as JSON);
D --> E(JavaScript Renders Results Bar);
F(Timer Every 5s) --> G(GET poll.php for Latest Tally);
G --> D;