Sondage simple - sans bdd - classe php - protection ip + cookie

Description

N'ayant pas trouvé de script de ce genre sur le web, j'ai décidé de le créer vite fait moi même. ^^

Donc c'est une classe de sondage très simpliste ayant pour but le fait de pouvoir être adaptée sur un site existant très rapidement (un seul fichier et non pas de multiples fichiers dans plusieurs dossiers comme certains scripts (qui sont néanmoins plus complets)).

Les résultats ainsi que les IP sont stockés dans 2 fichiers textes ayant pour extension php et débutant par <?php exit(); ?>, ce qui devrait surtout empêcher les visiteurs de pouvoir voir les IPs des votants.

Les résultats sont stockés dans le fichier dans l'ordre des réponses du sondage et sont séparés par des ";" donc attention si vous changez de vote : pensez à effacer les anciens fichiers contenant les ips et les résultats.

(Par contre, par défaut, on ne peux pas mettre deux sondages sur la même page avec cette classe (les boutons radio des 2 formulaires de vote auraient le même nom) , pour cela, il devrait être possible de rajouter un paramètre dans le constructeur qui prendrait pour valeur le "name" du <input type="radio"/>. Enfin c'est dur à expliquer. ^^)

Pour les barres de résultats, j'utilise tout simpleemnt une image gif de taille 10x1px dont la largeur est proportionnelle au pourcentage de résultats.

Source / Exemple :


<?php
class Sondage
{
	public $Question = "" ;//Question du sondage
	public $Choix = array() ;//Contient les différents choix possibles du sondage
	public $DejaVote = false;//True si le visiteur a déjà  voté, false (par défaut) sinon
	public $ListeIp = array() ;//Contient l'IP des visiteurs ayant déjà  voté (extrait de $this->FichierIp)
	public $Resultats = array() ;//Contient les résultats des votes (extrait de $this->FichierResultats)
	
	public $FichierIp ;//Adresse du fichier (avec .php pour extension impérativement) contenant les IP des visiteurs ayant déjà  votés (séparées par des ;)
	public $FichierResultats ;//Adresse du fichier (avec .php pour extension impérativement) contenant les résultats du sondage  (séparés par des ; et dans l'ordre de l'array $this->Choix)
		
	//Constructeur de la classe
	public function __construct ( $Question, $Choix, $FichierIp, $FichierResultats )
	{
		$this->Question = $Question ; 
		$this->Choix = $Choix ;
		$this->FichierIp = $FichierIp ;
		$this->FichierResultats = $FichierResultats ;
		
		//Si les fichiers IP et Resultats n'existent pas : les crée (possibilité de supprimer cette partie si vous créez les fichiers manuellement)
		if(!file_exists($FichierIp) OR !file_exists($FichierResultats)) {
			touch($FichierIp) ;
			touch($FichierResultats) ;
		}
		
		//Vérifie si le visiteur a déjà  voté (Vérification Cookie + IP)
		if(isset($_COOKIE['vote']) OR $this->VerifierIp($_SERVER["REMOTE_ADDR"]) === false) {
			$this->DejaVote = true ;
		}
	}
	//Vérifie si l'IP du visiteur est déjà  présente dans dans le fichier $FichierResultats
	private function VerifierIp ($ip)
	{
		$this->ListeIp = explode(";", file_get_contents($this->FichierIp, NULL, NULL, 16));
		if(!empty($this->ListeIp) AND in_array($ip, $this->ListeIp)){
			return false ;
		}
		return true ;
	}
	//Comptabilise le vote du Choix n° $NumVote : A UTILISER AVANT toute sortie (avant les balises <html><head> ...) car utilisation de la fonction setcookie()
	public function AjoutVote ($NumVote)
	{
		if($this->DejaVote === true) {
			return false ;
		}
		$this->Resultats = explode(";", file_get_contents($this->FichierResultats, NULL, NULL, 16));
		//Si premier vote : initialisation de $this->Resultats avec 0 votes pour chaque choix
		if(!isset($this->Resultats[0]{0})) {
			$Nb = sizeof($this->Choix) ;
			for($n=0;$n<$Nb;$n++) $this->Resultats[$n] = '0';
		}
		$this->Resultats[$NumVote]++ ;//Incrémentation du choix pour lequel le visiteur a voté
		
		$this->ListeIp[] = $_SERVER["REMOTE_ADDR"] ;//Ajout de l'IP du votant à  la liste
		
		//Ecriture des Résultats et des IP dans les fichiers
		if( !file_put_contents($this->FichierResultats, '<?php exit(); ?>'.implode(";", $this->Resultats) ) 
		OR !file_put_contents($this->FichierIp, '<?php exit(); ?>'.implode(";", $this->ListeIp) ) ) {
			return false ;
		}
		$this->DejaVote = true ;
		setcookie('vote', true, time()+3*30*24*60*60) ; //Mise en place d'un cookie valide 3 mois
		return true;
	}
	//Affiche les résultats du vote
	public function AfficherResultats ()
	{
		//Si $this->Resultats est vide : il n'a pas encore été recherché dans le fichier $this->FichierResultats (ou 0 votes : voir ci-dessous)
		if(empty($this->Resultats))
		{
			$this->Resultats = explode(";", file_get_contents($this->FichierResultats, NULL, NULL, 16));
			
			//Si $this->Resultats est toujours vide : 0 votes : initialisation de $this->Resultats
			if(empty($this->Resultats)) {
				$Nb = sizeof($this->Choix) ;
				for($n=0;$n<$Nb;$n++) $this->Resultats[] = 0;
			}
		}
		$TotalVotes = array_sum($this->Resultats) ;//Fait la somme de tous les valeurs de $this->Resultats pour avoir le nombre total de votant
		
		echo '<div style="border:1px solid black;padding:0 10px;width:450px;"><p<b>'.$this->Question.'</b></p><table style="margin-left:10px;">' ;
		
		//Parcourt l'array $this->Choix afin d'écrire les résultats en utilisant $id pour obtenir le résultat correspondant au choix
		foreach($this->Choix as $id=>$choix)
		{
			@$pourcentage = $this->Resultats[$id]*100/$TotalVotes ;
			echo '<tr><td><u>'.$choix.'</u> : </td><td><img src="bar.gif" height="10" width="'.(2*$pourcentage).'" />  '.number_format($pourcentage, 2, ',', '').' % ('.$this->Resultats[$id].')</td></tr>' ;
		}
		echo '</table><p><b>Total des votes : </b> '.$TotalVotes.'</p>' ;	
		if($this->DejaVote === true) {
			echo '<p>Vous avez déjà voté !</p>' ;
		}
		else {
			echo '<p><a href="?">Retourner au formulaire de vote</a></p>';
		}
		echo '</div>' ;
	}
	//Affiche le formulaire du vote
	public function AfficherFormulaire ()
	{
		echo '<div style="border:1px solid black;padding:0 10px;width:450px;"><form method="post"><p><b>'.$this->Question.'</b></p><table style="margin-left:10px;">' ;
		$disable = '';
		if($this->DejaVote === true) {
			$disable = ' disabled="disabled"';//Si le visiteur a déjà  voté : grise le formulaire si nécessaire
			echo '<p>Vous avez déjà voté !</p>' ;
		}
		foreach($this->Choix as $id=>$choix)
		{
			echo '<tr><td><input type="radio" name="choix" value="'.$id.'"'.$disable.' /></td><td><u>'.$choix.'</u></td></tr>' ;
		}
		echo '</table><p><input type="submit" value="Votez!" '.$disable.'/></p><p><a href="?resultats=1">Voir les résultats</a></p></form></div>' ;	
	}
}
/*

  • Exemple d'utilisation
  • /
$sondage = new Sondage('Quelle est votre couleur favorite ?', array('Vert', 'Jaune', 'Bleu'), 'ip.php', 'resultats.php') ; if( isset($_POST['choix']) ){ $sondage->AjoutVote(intval($_POST['choix'])); } echo '<html><body>' ; if($sondage->DejaVote === true OR isset($_GET['resultats'])){ $sondage->AfficherResultats() ; } else { $sondage->AfficherFormulaire(); }

Conclusion :


Je précise que c'est la première source que je poste ici et que je ne l'ai pas encore testée en approfondi.
Donc si vous avez la moindre remarque, suggestion, question ou décelez le moindre bug, n'hésitez pas ^^.
Enjoy ;-)

Codes Sources

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.