Sondage AJAX en PHP
Apprenez à créer un sondage AJAX en PHP qui enregistre les votes et affiche les résultats en direct sans recharger la page, avec fetch, JSON et MySQL.
Qu'est-ce qu'un sondage AJAX ?
Un sondage AJAX est un petit widget de vote qui permet à l'utilisateur de choisir une option, soumet ce vote au serveur en arrière-plan, puis affiche les résultats mis à jour — le tout sans recharger la page. AJAX (Asynchronous JavaScript and XML) est la technique qui consiste à échanger des données avec le serveur via JavaScript une fois la page déjà chargée.
Ce chapitre crée un sondage complet : une table MySQL pour stocker les options et leurs compteurs de votes, un script PHP qui enregistre un vote et renvoie le décompte actuel en JSON, et une petite quantité de JavaScript qui envoie le vote et affiche les résultats.
Si vous souhaitez actualiser en continu des données selon un minuteur (un tableau de scores en direct, un tableau de bord d'état), les mêmes briques de base s'appliquent — ce schéma s'appelle le polling, et nous le traitons en fin de chapitre.
Pourquoi utiliser AJAX pour un sondage ?
- Pas de rechargement de page. L'utilisateur reste sur la page ; seule la zone du sondage change. Cela paraît instantané et conserve le reste de la page (position de défilement, vidéo, saisie de formulaire) intacte.
- Moins de données transférées. Au lieu de renvoyer l'intégralité du document HTML, le serveur ne retourne que les compteurs de votes sous forme d'une petite charge utile JSON.
- Résultats en direct. Comme la réponse est constituée de données et non de balisage, vous pouvez réafficher immédiatement une barre de résultats et même la mettre à jour sur un minuteur pour refléter les votes d'autres utilisateurs.
Étape 1 — Créer la table de base de données
Chaque option de sondage correspond à une ligne. Nous stockons le texte de l'option et un compteur de votes cumulés.
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');Si vous débutez dans la création de tables, consultez Créer une table MySQL et Insérer des données.
Étape 2 — Créer le formulaire HTML
Le formulaire liste les options sous forme de boutons radio et réserve un conteneur pour les résultats.
<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>La value de chaque bouton radio correspond à l'id de l'option dans la base de données — c'est la seule chose que nous devons envoyer au serveur.
Étape 3 — Écrire le gestionnaire PHP
Le script PHP remplit deux rôles : enregistrer un vote (lorsqu'un vote est soumis) et renvoyer les résultats actuels en JSON. Utilisez toujours des instructions préparées afin qu'une valeur provenant du navigateur ne puisse jamais être interprétée comme du 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']);
}Le transtypage de l'id entrant avec (int) et sa liaison via :id garantissent que la valeur est traitée strictement comme un nombre, et non comme une partie de la requête. Pour en savoir plus, lisez Instructions préparées PHP et json_encode().
Étape 4 — Envoyer le vote avec JavaScript
Nous interceptons l'événement submit du formulaire, envoyons l'option sélectionnée avec fetch(), puis affichons une barre de résultats à partir de la réponse 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() est ce qui empêche le navigateur d'effectuer une soumission complète, ce qui est tout l'intérêt d'AJAX. Le pourcentage est calculé côté client à partir des compteurs renvoyés par le serveur, de sorte que la barre correspond toujours aux données les plus récentes.
Étape 5 — Maintenir les résultats en direct avec le polling
Jusqu'ici, les résultats ne se mettent à jour que lorsque cet utilisateur vote. Pour refléter les votes d'autres utilisateurs, interrogez le serveur sur un minuteur — demandez le dernier décompte toutes les quelques secondes et réaffichez :
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.Comme le gestionnaire PHP renvoie le décompte à chaque requête (vote ou non), un simple GET suffit pour obtenir des chiffres frais. Choisissez l'intervalle avec soin : un intervalle court paraît plus réactif mais génère davantage de requêtes. Pour des données devant être véritablement en temps réel, les WebSockets ou les Server-Sent Events conviennent mieux que le polling à intervalle fixe.
Pièges courants
- Oublier
event.preventDefault(). Sans lui, le formulaire recharge la page et l'appel AJAX est annulé en cours de route. - Faire confiance à l'id de l'option. Castez-le toujours, validez-le et utilisez une instruction préparée ; ne concaténez jamais
$_POSTdans du SQL. - Double comptage. Cet exemple de base permet à un même navigateur de voter plusieurs fois. En production, limitez par session, cookie ou adresse IP.
- Polling trop agressif. Un intervalle d'une seconde sur une page très fréquentée peut surcharger le serveur ; 3 à 10 secondes suffisent généralement.
Résumé
Un sondage AJAX associe une table MySQL, un endpoint PHP qui enregistre un vote et renvoie le décompte en JSON, et du JavaScript qui soumet avec fetch() et affiche les résultats — sans rechargement de page. Ajoutez un setInterval de polling pour maintenir les chiffres à jour pour tout le monde.
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;