Comment faire un sondage en PHP

Le sondage, tout comme le forum, les news, fait partie des scripts PHP les plus usités sur les différents sites WEB.

Nous allons donc voir comment réaliser un tel script, et ce, toujours en adoptant la méthode la plus simple possible.

Pour cela, réfléchissons aux pages dont nous allons avoir besoin pour réaliser un sondage (je vous rappelle qu'avant de se lancer dans la composition d'un script, une petite réflexion sur papier s'impose toujours : il faut savoir résister à l'appel du clavier).

On aura alors :
  • la page qui contiendra le sondage, qui permettra également aux visiter de voter pour le sondage (donc la page index.php).
  • une page qui servira à voir les résultats du sondage (que l'on nommera par exemple sondage_resultats.php et qui sera également présente dans le même répertoire que les deux précédentes).
  • une page permettant au webmaster d'insérer un sondage (la page insert_sondage.php, page que l'on placera dans un répertoire admin par exemple)


Et voila :)

Ensuite, en ce qui concerne les tables SQL, faisons également une petite réflexion pour savoir combien de tables nous allons avoir besoin.

A priori, vu qu'un sondage comporte d'une part des questions, et d'autres part des réponses, on peut dire que l'on aura besoin de deux tables :
  • une table qui contiendra toutes les questions du sondage (que l'on nommera sondage_questions).
  • une table qui contiendra toutes les différentes réponses possibles aux différentes questions (table que l'on nommera sondage_reponses).


Détaillons alors le contenu de ces tables.
La table sondage_questions contiendra :
  • un attribut id de type INT avec une option de type AUTO_INCREMENT : cet attribut fera la distinction entre nos différents sondages.
  • un attribut question de type VARCHAR(150) : cet attribut donnera la question du sondage (150 caractères devraient largement suffire pour une question).


En ce qui concerne la table sondage_reponses on aura :
  • un attribut id de type INT avec une option de type AUTO_INCREMENT : l'attribut qui nous permettra de distinguer les réponses à nos sondages.
  • un attribut id_sondage de type INT: l'attribut qui nous permettra de rattacher la réponse au sondage auquel se rapporte cette question.
  • un attribut reponse de type VARCHAR(100) : cet attribut donnera une des réponses du sondage (100 caractères devraient largement suffire pour une réponse).
  • un attribut nb_reponses de type INT : attribut qui donnera le nombre de vote pour cette réponse.


Voici alors le schéma SQL de nos deux tables (donc à insérer dans votre PHPMyAdmin par exemple).

La table sondage_questions :

table_sondage_questions.sql
CREATE TABLE sondage_questions (
id int(6) NOT NULL auto_increment,
question VARCHAR(150) NOT NULL,
PRIMARY KEY (id)
) TYPE=MyISAM;


La table sondage_reponses :

table_sondage_reponses.sql
CREATE TABLE sondage_reponses (
id int(6) NOT NULL auto_increment,
id_sondage INT(6) NOT NULL,
reponse VARCHAR(100) NOT NULL,
nb_reponses INT(6) NOT NULL,
PRIMARY KEY (id)
) TYPE=MyISAM;


Avant de poursuivre notre algorithme (en fait, juste pour vous donner une idée de ce que contiendra les tables pour mieux comprendre le code que nous allons écrire pour notre index.php), nous allons prendre l'exemple d'un sondage composé d'une question et de plusieurs réponses possibles.

Voici par exemple le contenu de la table sondage_questions :

idQuestion
1Que pensez-vous de mon site ?


Et celui de la table sondage_reponses :

idid_sondagereponsenb_reponses
11Je kiff :)25
21Sympa :)14
31Po mal...8
41Po terrible :(3


Que contiendra alors notre index.php ?

Il faudra tout d'abord sélectionner la question du sondage en cours, c'est-à-dire la question de notre table sondage_sondages qui aura l'id le plus grand, puis les réponses correspondantes à ce même sondage, c'est-à-dire les éléments de la table sondage_reponses qui auront l'attribut id_sondage égal à l'id du sondage que l'on vient de sélectionner.

Après cela, on affichera notre formulaire permettant aux visiteurs de voter.

Et, c'est tout pour notre index.php :)

On aura alors, par exemple, pour notre page index.php :

index.php
<?php
// on teste si formulaire de vote a été validé
if (isset($_POST['go']) && $_POST['go']=='Vote') {
if (!isset($_POST['choix']) || !isset($_POST['sondage_en_cours'])) {
$erreur = 'Aucune réponse n\'a été choisie.';
}
// on teste si le visiteur a bien choisi une réponse avant d'avoir clické sur "Vote". On teste aussi si la variable $_POST['sondage_en_cours'] n'est pas vide
if (empty($_POST['choix']) || empty($_POST['sondage_en_cours'])) {
$erreur = 'Au moins un des champs est vide.';
}
else {
// là le visiteur à choisi une réponse
// on se connecte à notre base
$base = mysql_connect ('serveur','login','pawword');
mysql_select_db ('nom_base',$base);

// on prépare notre requête : on ajoute un vote pour la réponse choisie par le votant
$sql ='UPDATE sondage_reponses SET nb_reponses = nb_reponses + 1 WHERE id_sondage="'.$_POST['sondage_en_cours'].'" AND id="'.$_POST['choix'].'"';

// on lance la requête
mysql_query ($sql) or die ('Erreur SQL !'.$sql2.'<br />'.mysql_error());

// on ferme la connexion à la base de donnée
mysql_close ();

$erreur = 'Merci d\'avoir voté :)';
}
}
?>

<html>
<head>
<title>Index de notre sondage :)</title>
</head>

<body>
<?php
// on se connecte à notre base de données
$base = mysql_connect ('localhost','root','');
mysql_select_db ('howto_sondage',$base);

// on prépare une requête pour sélectionner l'id et la question du dernier sondage (on sélectionne les questions, et on en prend qu'une (le LIMIT 0,1) et ce, dans un ordre décroissent (DESC), soit en fait, la dernière question posée).
$sql = 'SELECT id, question FROM sondage_questions ORDER BY id DESC LIMIT 0,1';

// on lance la requête
$req = mysql_query ($sql) or die ('Erreur SQL !<br />'.$sql.'<br />'.mysql_error());

// on récupère le résultat dans un tableau associatif
$data = mysql_fetch_array ($req);

$nb_sondage = mysql_num_rows($req);

if ($nb_sondage == 0) {
echo 'Aucun sondage.';
}
else {
// on libère l'espace mémoire alloué à cette requête
mysql_free_result ($req);

// on affiche la question
echo stripslashes(htmlentities(trim($data['question']))),'<br />';

// on prepare l'affichage de notre formulaire permettant de voter
echo '<form action = "index.php" method = "post">';

// on prépare une requête permettant de sélectionner les réponses possibles se rapportant à ce même sondage
$sql = 'SELECT id, reponse FROM sondage_reponses WHERE id_sondage="'.$data['id'].'"';

// on lance la requête
$req = mysql_query($sql) or die('Erreur SQL !<br />'.$sql.'<br />'.mysql_error());

// on prépare notre boucle pour afficher les différents choix possibles de réponses
while ($donnees = mysql_fetch_array($req)) {
// on affiche des boutons radio pour les différents choix de réponses possibles
echo '<input type="radio" name="choix" value="' , $donnees['id'] , '"> ' , stripslashes(htmlentities(trim($donnees['reponse']))) , '<br />';
}
?>
<input type = "hidden" name = "sondage_en_cours" value = "<?php echo $data['id']; ?>">
<input type = "submit" name="go" value = "Vote">
</form>
<?php
}

// on libère l'espace mémoire alloué à cette requête
mysql_free_result ($req);

// on ferme la connection à notre base de données
mysql_close ();
?>
<br /><br />
<a href="sondage_resultats.php">Voir les résultats</a>
<?php
// on affiche les erreurs éventuelles
if (isset($erreur)) echo '<br /><br />',$erreur;
?>
</body>
</html>




Le sondage est alors déjà opérationnel.

En effet, nous pouvons déjà afficher le formulaire nous permettant de voter, nous pouvons même voter, mais il nous reste tout de même la page sondage_resultats.php à écrire, page qui nous permettra de voir les résultats du sondage en cours.

Dans cette page, nous allons placer les différentes réponses les unes à la suite des autres, placer en face de chaque réponse le pourcentage de vote pour cette réponse, et enfin, en bas de la page, nous allons afficher le nombre de votre total pour ce sondage.


Nous aurons alors, par exemple, pour la page sondage_resultats.php :

sondage_resultats.php
<html>
<head>
<title>Résultats des votes</title>
</head>

<body>
<?php
// on se connecte à notre base de données
$base = mysql_connect ('localhost','root','');
mysql_select_db ('howto_sondage',$base);

// on selectionne la question et l'id du sondage en cours
$sql = 'SELECT id, question FROM sondage_questions ORDER BY id DESC LIMIT 0,1';

// on lance la requête
$req = mysql_query ($sql) or die ('Erreur SQL !<br />'.$sql.'<br />'.mysql_error());

// on récupère le résultat dans un tableau associatif
$data = mysql_fetch_array ($req);

// on libère l'espace mémoire alloué à cette requête

$nb_sondage = mysql_num_rows($req);
mysql_free_result ($req);

if ($nb_sondage == 0) {
echo 'Aucun sondage.';
}
else {

// on affiche la question
echo stripslashes(htmlentities(trim($data['question']))),'<br />';

// on déclare un tableau qui contiendra les réponses de notre sondage
$tableau_reponses = array();

// on déclare un tableau qui contiendra le nombre de réponse à chaque question
$tableau_nb_reponses = array();

// on selectionne les reponses de ce sondage
$sql = 'SELECT reponse, nb_reponses FROM sondage_reponses WHERE id_sondage="'.$data['id'].'"';

// on lance la requête
$req = mysql_query($sql) or die('Erreur SQL !<br />'.$sql.'<br />'.mysql_error());

// on prépare notre boucle pour récupérer les différents choix possibles de réponses
while ($data = mysql_fetch_array($req)) {
// on place ces valeurs dans nos deux tableaux
$tableau_reponses[] = $data['reponse'];
$tableau_nb_reponses[] = $data['nb_reponses'];
}

// on libère l'espace mémoire alloué à cette requête
mysql_free_result ($req);

// on ferme la connection à notre base de données
mysql_close ();

// on compte le nombre de réponses possible de notre sondage
$nb_reponses_du_sondage = count ($tableau_reponses);

// on compte le nombre total de réponses pour ce sondage
$nb_total_reponse = array_sum ($tableau_nb_reponses);

// on teste le nombre de vote
if ($nb_total_reponse == 0) {
// cas où personne n'a voté
echo 'Aucun vote pour l'instant';
}
else {
// cas où quelqu'un a déjà voté
for ($i = 0; $i < $nb_reponses_du_sondage; $i++) {
// on affiche une réponse
echo $tableau_reponses[$i];

// on calcul le pourcentage de cette réponse
$pourcentage = ($tableau_nb_reponses[$i] * 100) / $nb_total_reponse;

// on arrondi ce calcul à un chiffre après la virgule
$pourcentage = round ($pourcentage, 1);

// on affiche le pourcentage
echo ' ',$pourcentage,' %<br />';
}

// on affiche le nombre total de votes
echo '<br /><br />Nombre de votes : ', $nb_total_reponse;
}
}
?>
</body>
</html>


Enfin, il nous reste à écrire la page de la partie admin permettant d'enregistrer un nouveau sondage.
Cette page sera un peu spécial, puisqu'elle utilise des variables dynamiques.

En effet, combien de réponses possibles aura notre nouveau sondage ?
On ne peut le savoir, et par conséquent, il va falloir générer autant de champ de formulaire de type text que de réponses possibles.

admin.php
<?php
// on teste si l'utilisateur a validé le formulaire et qu'il cherche à insérer le sondage dans la base, et non à ajouter une réponse au sondage
if (isset($_POST['go']) && $_POST['go']=='Valider') {
if (!isset($_POST['question']) || empty($_POST['question'])) {
$erreur = 'Votre question est vide.';
}
else {
// on va regarder si l'utilisateur n'a pas laissé un champ vide
$valid_form = 1;
for ($i=1; $i<=$_POST['nb_reponses']; $i++){
$temp = "reponse_$i";
if (isset($_POST[$temp])) $value=$_POST[$temp];
if (empty($value)) $valid_form = 0;
}
if ($valid_form == 0) {
$erreur = 'Au moins une de vos réponse est vide.';
}
else {
// on se connecte à notre base de données
$base = mysql_connect ('serveur', 'login', 'password');
mysql_select_db('nom_base', $base);

// on insère notre question
$sql = 'INSERT INTO sondage_questions VALUES("","'.mysql_escape_string($_POST['question']).'")';
mysql_query($sql) or die('Erreur SQL !'.$sql.'<br />'.mysql_error());

$id_sondage = mysql_insert_id();

// on insère les réponses possibles à ce sondage
for ($i=1; $i<=$_POST['nb_reponses']; $i++){
$temp = "reponse_$i";
if (isset($_POST[$temp])) $value=$_POST[$temp];

$sql = 'INSERT INTO sondage_reponses VALUES("","'.$id_sondage.'","'.mysql_escape_string($value).'", "0")';
mysql_query($sql) or die('Erreur SQL !'.$sql.'<br />'.mysql_error());

}
// on redirige l'utilisateur à l'accueil du sondage
header("location: ../index.php");
exit();
}
}

}
?>
<html>
<head>
<title>Insertion d'un nouveau sondage</title>
</head>

<body>

<form action="insert_sondage.php" method="post">
<table>
<tr><td>
[b]Question :[/b]
</td><td>
<input type="text" name="question" value="<?php if (isset($_POST['question'])) echo stripslashes(htmlentities(trim($_POST['question']))); ?>">
</td></tr>
<?php
// on teste si la variable $_POST['nb_reponses'] est définie ou pas. Si elle ne l'est pas, on la défini à 1 (un sondage aura au moins une reéponse possible :)
if (!isset($_POST['nb_reponses'])) $_POST['nb_reponses'] = 1;

// si l'utilisateur a clické sur 'Ajouter une réponse' on incrémente la variable $_POST['nb_reponses'], ce qui va nous permettre de rajouter un champ de type text (pour la nouvelle réponse possible) à notre formulaire
if (isset($_POST['go']) && $_POST['go']=='Ajouter une réponse') $_POST['nb_reponses']++;

for ($i=1; $i<=$_POST['nb_reponses']; $i++){
$temp = "reponse_$i";
if (isset($_POST[$temp])) $value=$_POST[$temp];
echo '<tr><td><td><input type="text" name="reponse_'.$i.'" value="';
if (isset($value)) echo stripslashes(htmlentities(trim($value)));
echo '"></td></tr>';
unset($value);
}

// on passe à notre formulaire le nombre de réponse au sondage
echo '<input type="hidden" name="nb_reponses" value="'.$_POST['nb_reponses'].'">';
echo '<tr><td><input type="submit" name="go" value="Ajouter une réponse"></td></tr>';
echo '<tr><td>&nbsp;</td></tr>';
echo '<tr><td><input type="submit" name="go" value="Valider"></td></tr>';

?>
</table>
</form>
<?php
if (isset($erreur)) echo '<br /><br />',$erreur;
?>
</body>
</html>


Et voila :)

Notre sondage est à présent terminé.
Il ne reste plus qu'à rédiger l'interface d'administration permettant d'ajouter des nouveaux sondages, des nouvelles réponses.
Interface que je vous laisse réaliser :)

Que faire en plus ?

Afin d'améliorer ce sondage, vous pouvez pourquoi pas établir un système retenant l'adresse IP d'un votant (afin qu'il ne puisse pas voter plusieurs fois), voir même l'utilisation d'un cookie se souvenant que le visiteur à déjà voté.

Et pourquoi ne pas tenter de faire un graphique en barre comme sur lephpfacile dont la taille des barres varient suivant le nombre de votes ?

A vos claviers.
LoadingChargement en cours