Comment créer un système de notations en PHP?

Attention, depuis PHP 5.5.0, certaines extensions SQL sans doute utilisées dans ce tutoriel peuvent être obsolètes et seront supprimées dans le futur, vous devez donc adapter les codes! Exemples ici.
Dans ce tutoriel, nous allons voir comment créer un petit système de notations tout simple en PHP. Pour permettre la notation, nous allons afficher un simple formulaire (select) noté de 0 à 10 et le résultat sera donné sous forme textuel (nombre des notes, total des notes et note) ainsi qu'une notation visuel représenté par des étoiles. Notez qu'il existe sur le web des systèmes de notations bien mieux conçue et plus perfectionné...la, c'est juste pour comprendre le principe de base . Une démonstration est visible sur le site de testes » http://creer.ton.site.free.fr.

Les notes étant enregistrées en base de données, nous allons donc commencer par la :
--
-- Structure de la table `note`
--
 
CREATE TABLE IF NOT EXISTS `note` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `id_page` int(11) NOT NULL,
  `note` int(11) NOT NULL,
  `ip` varchar(15) COLLATE latin1_general_ci NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci AUTO_INCREMENT=1 ;
​ Nous créons donc une table nommé "note" contenant 4 champs :
  1. id en auto incrémentation.
  2. id_page qui va enregistrer l'identifiant de la page.
  3. note pour enregistrer la note donné par l'utilisateur.
  4. ip pour enregistrer l'ip de l'utilisateur.
Nous allons à présent créer un fichier nommé "index.php" :
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="fr-fr">
	<head>
		<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1" />
		<title>Teste vote</title>
	</head>
	
	<body>
		
	</body>
</html>
Pour simplifier au maximum la mise en place de ce système nous allons créer une fonction qui fera appel à une fichier nommé "fonctions-vote.php" et qui contiendra l'ensemble du code de notations. Le code que nous allons concevoir fera également appel à la création d'un cookie.

Comme dit plus haut, nous allons créer une fonction et pour ce tutoriel nous allons nommer notre fonction "notation". Cette fonction va faire appel à 2 arguments pour fonctionner. Le premier argument sera l'identifiant de la page et le second l'ip de l'utilisateur.
Toujours dans la page "index.php" juste après la balise "<body>" nous allons faire appel à cette fameuse fonction de la manière suivante :
<?php
        include('fonctions-vote.php');
	notation('5',$ip_vote);
?>
Pour bien comprendre :
notation() est le nom de la fonction que nous allons créer.
'5' est le premier argument passé en paramètre de la fonction et correspond à l'identifiant de la page. Ce chiffre (pour l'exemple) peut être remplacé par une variable sous condition de supprimer les simples quotte (').
$ip_vote est le second argument et correspond à l'ip de l'utilisateur.

La page "index.php" doit donc ressembler à ceci :
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="fr-fr">
	<head>
		<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1" />
		<title>Teste vote</title>
	</head>
	
	<body>
		
		<?php
            include('fonctions-vote.php');
			notation('5',$ip_vote);
		?>
		
	</body>
</html>
​ Créer un dossier nommé "images-vote" contenant ces 2 images étoileloading.

Passons maintenant à la création de la fonction. Créer un fichier nommé "fonctions-vote.php".
La première chose que nous allons faire, c'est déclarer les variables pour accéder à la base de données. Dans mon cas, ces variables correspondent à une base de données nommé "votes" créée sous Wampserver, vous devez donc les modifier pour votre propre base de données.
<?php
	
	//Variable de connexion BDD
	$nom_du_serveur ="localhost";
	$nom_de_la_base ="votes";
	$nom_utilisateur ="root";
        $passe ="";
​ Nous allons ensuite créer une fonction qui va nous permettre de récupérer l'ip de l'utilisateur :
	//Fonction pour l'ip
	function getIp()
	{
		if(isset($_SERVER['HTTP_X_FORWARDED_FOR']))
		{
			$ip_vote = $_SERVER['HTTP_X_FORWARDED_FOR'];
		}
		elseif(isset($_SERVER['HTTP_CLIENT_IP']))
		{
			$ip_vote = $_SERVER['HTTP_CLIENT_IP'];
		}
		else
		{
			$ip_vote = $_SERVER['REMOTE_ADDR'];
		}
		return $ip_vote;
	}
	//Ip utilisateur
	$ip_vote = getIp();
​ Ceci fait, on se connecte à la base de données :
	//Connexion à la base de données
	mysql_connect("$nom_du_serveur","$nom_utilisateur","$passe");
	//Vérification d'accès à la base de données
	mysql_select_db("$nom_de_la_base")  or die ('Erreur :'.mysql_error());
​ Nous arrivons maintenant à la création de la fonction "notation".
	//Fonction pour la notation
	function notation($id_vote,$ip_vote){
		//Ici le reste du code
	}
​ Dans un premier temps on vérifie si l'utilisateur à déja voté ou pas.
    //L'utilisateur a t'il déjà voté?
    $deja_voter = mysql_query("SELECT ip FROM note WHERE ip = '".mysql_real_escape_string($ip_vote)."' AND id_page = '".mysql_real_escape_string($id_vote)."'");
​ Si il n'a pas encore noté, on lui affiche le formulaire de notations :
	//L'utilisateur n'a pas voté, on montre le formulaire
    if(mysql_num_rows($deja_voter) == 0)
    {
        echo ' <form name="monform" id="monform" method="post"> 
		<label>Noter cet article</label> 
		<select name="note" onchange="javascript:submit(this)"> 
		<option value="">Note</option>
		<option value="0">0</option>
		<option value="1">1</option>
		<option value="2">2</option>
		<option value="3">3</option>
		<option value="4">4</option>
		<option value="5">5</option>
		<option value="6">6</option>
		<option value="7">7</option>
		<option value="8">8</option>
		<option value="9">9</option>
		<option value="10">10</option>
		</select>
		</form> ';
	}
​ Si l'utilisateur peut noter, on va créer au sein de la fonction un cookie qui sera vérifié lors du poste du formulaire pour voir si l'utilisateur tente de noter plusieurs fois :
    //Si action de valider et que la note est différent de vide
    if(isset($_POST['note']) && $_POST['note'] != NULL){
        //On vérifie si le cookie existe et si tel est le cas, c'est que l'utilisateur tente de voter plusieurs fois
        if(isset($_COOKIE["deja_voter"]) && $_COOKIE["deja_voter"] == $id_vote){
            die ("Un seul vote autorisé ... merci!");
		}
        //Note de l'utilisateur
        $note = $_POST['note'];
​ On enregistre le tout en base de données :
	//Insertion en BDD
	$insert = mysql_query("INSERT INTO note VALUES ( '', '".mysql_real_escape_string($id_vote)."', '".mysql_real_escape_string($note)."', '".mysql_real_escape_string($ip_vote)."' ) ");
	//Si il y a une erreur
	if(!$insert) {
		die('Requête invalide : ' . mysql_error());
	}
​ Si tout est correcte, on affiche un message et on effectue une redirection de la page pour que la note soit prise en compte :
	//Tout est ok, on informe et on redirige
	else{
        //On créer un cookie d'une durée de 20 secondes pour éviter les retours en arrière
        setcookie('deja_voter',$id_vote,(time() + 20));
		
		echo 'Merci d\'avoir noté cet article!<br/>
		Chargement en cours <img alt="Loading" src="images-vote/loading.gif" style="width:32px;height:32px;"/>
		<script type="text/javascript">
		document.getElementById("monform").innerHTML = "";
		window.setTimeout(function(){self.location.href="'.$_SERVER['REQUEST_URI'].'";},3000);
		</script>';
	}
}
​ Nous allons maintenant récupérer le nombre de votes :
    //Combien d'utilisateurs ont votés?
    $nombre_vote = mysql_query("SELECT id FROM note WHERE id_page = '".mysql_real_escape_string($id_vote)."'");
    $total_vote = mysql_num_rows($nombre_vote);
    if($total_vote != 0){
        echo 'Nombre de vote : '.$total_vote.'<br/>';
	}
​ On calcul le total des notes :
    //Total des votes des utilisateurs
    $calcul_vote = mysql_query("SELECT SUM(note) AS totalmoyenne FROM note WHERE id_page = '".mysql_real_escape_string($id_vote)."'");
    $data = mysql_fetch_array($calcul_vote);
    $total_calcul_vote = $data['totalmoyenne'];
    if($total_calcul_vote != 0){
        echo 'Total des votes : '.$total_calcul_vote.'<br/>';   
	}
​ On calcul la moyenne des notes que l'on arrondi à 2 chiffres après la virgule :
    //Moyenne des votes des utilisateurs
    if($total_vote != NULL && $total_calcul_vote != NULL){
        $moyenne = number_format($total_calcul_vote/$total_vote, 2, ',', '');
​ Si les 2 chiffres après la virgule sont 2 zéro, on les suppriment pour obtenir un entier :
echo 'Note : '.str_replace(',00','',$moyenne).'/10';
​ Pour afficher les étoiles, on utilise une simple boucle for() :
	//On affiche les étoiles
	for($i=1; $i<=$moyenne;$i++){
		echo '<img alt="'.$i.'" src="images-vote/etoile.png" style="width:32px;height:32px;"/>';
	}
}
​ Si il n'y a pas eu de votes :
    else{
        echo 'Aucun vote pour le moment.';
    }
?>
​ Le fichier "fonctions-vote.php" dans son intégralité :
<?php
	
	//Variable de connexion BDD
	$nom_du_serveur ="localhost";
	$nom_de_la_base ="votes";
	$nom_utilisateur ="root";
	$passe ="";
	
	//Fonction pour l'ip
	function getIp()
	{
		if(isset($_SERVER['HTTP_X_FORWARDED_FOR']))
		{
			$ip_vote = $_SERVER['HTTP_X_FORWARDED_FOR'];
		}
		elseif(isset($_SERVER['HTTP_CLIENT_IP']))
		{
			$ip_vote = $_SERVER['HTTP_CLIENT_IP'];
		}
		else
		{
			$ip_vote = $_SERVER['REMOTE_ADDR'];
		}
		return $ip_vote;
	}
	//Ip utilisateur
	$ip_vote = getIp();
	
	//Connexion à la base de données
	mysql_connect("$nom_du_serveur","$nom_utilisateur","$passe");
	//Vérification d'accès à la base de données
	mysql_select_db("$nom_de_la_base")  or die ('Erreur :'.mysql_error());
	
	//Fonction pour la notation
	function notation($id_vote,$ip_vote){
		
		//L'utilisateur a t'il déjà voté?
		$deja_voter = mysql_query("SELECT ip FROM note WHERE ip = '".mysql_real_escape_string($ip_vote)."' AND id_page = '".mysql_real_escape_string($id_vote)."'");
		
		//L'utilisateur n'a pas voté, on montre le formulaire
		if(mysql_num_rows($deja_voter) == 0)
		{
			echo '<form name="monform" id="monform" method="post">
			<label>Noter cet article</label>
			<select name="note" onchange="javascript:submit(this)">
			<option value="">Note</option>
			<option value="0">0</option>
			<option value="1">1</option>
			<option value="2">2</option>
			<option value="3">3</option>
			<option value="4">4</option>
			<option value="5">5</option>
			<option value="6">6</option>
			<option value="7">7</option>
			<option value="8">8</option>
			<option value="9">9</option>
			<option value="10">10</option>
			</select>
			</form>';
		}   
		
		//Si action de valider et que la note est différent de vide
		if(isset($_POST['note']) && $_POST['note'] != NULL){
			//On vérifie si le cookie existe et si tel est le cas, c'est que l'utilisateur tente de voter plusieurs fois
			if(isset($_COOKIE["deja_voter"]) && $_COOKIE["deja_voter"] == $id_vote){
				die ("Un seul vote autorisé ... merci!");
			}
			//Note de l'utilisateur
			$note = $_POST['note'];
			//Insertion en BDD
			$insert = mysql_query("INSERT INTO note VALUES ( '', '".mysql_real_escape_string($id_vote)."', '".mysql_real_escape_string($note)."', '".mysql_real_escape_string($ip_vote)."' ) ");
			//Si il y a une erreur
			if(!$insert) {
				die('Requête invalide : ' . mysql_error());
			}
			//Tout est ok, on informe et on redirige
			else{
				//On créer un cookie d'une durée de 20 secondes pour éviter les retours en arrière
				setcookie('deja_voter',$id_vote,(time() + 20));
				
				echo 'Merci d\'avoir noté cet article!<br/>
				Chargement en cours <img alt="Loading" src="images-vote/loading.gif" style="width:32px;height:32px;"/>
				<script type="text/javascript">
				document.getElementById("monform").innerHTML = "";
				window.setTimeout(function(){self.location.href="'.$_SERVER['REQUEST_URI'].'";},3000);
				</script>';
			}
		}
		
		//Combien d'utilisateurs ont votés?
		$nombre_vote = mysql_query("SELECT id FROM note WHERE id_page = '".mysql_real_escape_string($id_vote)."'");
		$total_vote = mysql_num_rows($nombre_vote);
		if($total_vote != 0){
			echo 'Nombre de vote : '.$total_vote.'<br/>';
		}
		
		//Total des votes des utilisateurs
		$calcul_vote = mysql_query("SELECT SUM(note) AS totalmoyenne FROM note WHERE id_page = '".mysql_real_escape_string($id_vote)."'");
		$data = mysql_fetch_array($calcul_vote);
		$total_calcul_vote = $data['totalmoyenne'];
		if($total_calcul_vote != 0){
			echo 'Total des votes : '.$total_calcul_vote.'<br/>';   
		}
		
		//Moyenne des votes des utilisateurs
		if($total_vote != NULL && $total_calcul_vote != NULL){
			$moyenne = number_format($total_calcul_vote/$total_vote, 2, ',', '');
			//Si les 2 chiffres après la virgule sont 2 zéros, on les suppriment pour obtenir un entier
			echo 'Note : '.str_replace(',00','',$moyenne).'/10';
			//On affiche les étoiles
			for($i=1; $i<=$moyenne;$i++){
				echo '<img alt="'.$i.'" src="images-vote/etoile.png" style="width:32px;height:32px;"/>';
			}
		}
		else{
			echo 'Aucun vote pour le moment.';
		}
	}
?>
​ Et voila, c'est finit .

Selon ce que vous faites du code, il est possible que la création du cookie au sein de la fonction pose un problème de "header". Dans ce cas, déplacer le code de création du cookie avant le DOCTYPE et pensez à le supprimer de la fonction :
<?php
	//On créer un cookie d'une duréé de 20 secondes pour éviter les retours en arrière
	if(isset($_POST['note']) && $_POST['note'] != NULL){
		setcookie('deja_voter',$id_transmit,(time() + 20));
	}
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="fr-fr">
	<head>
		<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1" />
		<title>Teste vote</title>
	</head>
	
	<body>
		
		<?php
			include('fonctions-vote.php');
			notation('5',$ip_vote);
		?>
		
	</body>
</html>
$id_transmit correspondant à l'identifiant de la page.
Voir/déposer un commentaire (3) | Signaler un problème