Aller au menu - Aller au contenu

Like button

compteur "j'aime", AJAX

Pour accéder à cette section
Connectez-vous !
connexion_rpx

Offre d'emploi : Développeur Web PHP/Drupal (H/F)

Page 1 
Auteur Message
1 visiteur sur ce sujet (1 Anonyme)
Page 1 
Hors ligne jcooleman # Posté le 04/02/2012 à 16:33:45

Bonjour bonjour,



J'ai monté sur mon site web un système de "j'aime" ou "like" (comme Facebook), c'est à dire en gros : un compteur qui va stocker dans la bdd le nombre de clics qui ont été fait sur le bouton "like". J'ai utilisé du AJAX de telle façon que le nombre stocké dans la bdd soit incrémenté de 1 à chaque clic.
J'ai bloqué la fonction javascript après un clic, mais à supposer qu'une personne actualise sa page, elle pourra recliquer plusieurs fois. Il faut donc que ce clic soit limité à un par adresse IP. Par conséquent, je pensais utiliser $_SERVER[REMOTE_ADDR] et l'utiliser comme condition de l'incrémentation dans mon fichier PHP que j'appelle par AJAX. Voilà à quoi ca ressemble :

Code : PHP
1
2
3
4
5
6
7
8
9
<?php 
if ($_SERVER['IP'] != $_SERVER[REMOTE_ADDR]) {
	$selected_article = $_GET['checkArticle'];
	$pdo_options[PDO::ATTR_ERRMODE] = PDO::ERRMODE_EXCEPTION;
	$bdd = new PDO('mysql:host=localhost;dbname=BDD', 'root', 'root', $pdo_options);
	$reponse = $bdd->query("UPDATE articles SET compteur_article = compteur_article +1 WHERE id= '$selected_article'");
        $_SERVER['IP'] = $_SERVER[REMOTE_ADDR];
}
?>


Ca ne fonctionne même pas un peu : quoiqu'il arrive il continue d'incrémenter à chaque clic. Je n'attend pas une réponse toute faite, j'aimerai juste comprendre pourquoi cela ne fonctionne pas. Est-ce quelque chose que je n'aurai pas bien compris avec les superglobales ou le problème est-il du coté d'ajax?

Je suis en train de me dire que je ne vais pas avoir d'autres choix que de créer une table de données juste pour stocker les adresses IP de ceux qui ont déjà cliqué sur le bouton... Existe-t-il une solution plus simple?
Merci d'avance les gars ;)

NB : J'ai cherché sur les forums ici mais je n'ai pas trouvé quelqu'un qui ait été dans la même situation que moi, si j'ai raté le bon topic alors j'en suis désolé, envoyez moi le lien s'il vous plait :)
Publicité # Posté le 04/02/2012 à 16:33:45

Hors ligne Yalio # Posté le 04/02/2012 à 18:00:41
Do you want a salad?
Avatar

Salut,
As-tu vérifié ta base ? Car $_SERVER est un array comme un autre, il ne faut donc pas oublier les guillemets : $_SERVER['REMOTE_ADDR']. :)

Deux trois ressources utiles et méconnues
Google, le guide du zCode, lebonforfait.fr (topic) et d'autres à venir.

« Oubliez les versions dépassées des navigateurs. Les supporter, c'est retarder leur disparition ». de warpShadow.
Image utilisateur Même Clint Eastwood le savait !
 
Hors ligne jcooleman # Posté le 04/02/2012 à 19:21:06

Non non t'inquiète, j'avais déjà vérifié et ca marche dans les deux cas : $_SERVER['REMOTE_ADDR'] ou $_SERVER[REMOTE_ADDR] marchent aussi bien l'un que l'autre.
PS : j'ai revérifié dans le doute pour pas dire de conneries ;)

NB : Autre problème auquel je pense : si $_SERVER['REMOTE_ADDR'] et $_SERVER['IP'] sont bien tout deux des array, ca signifie qu'ils peuvent enregistrer autant d'adresses IP qu'ils veulent ou qu'une seule à la fois? Parce qu'en écrivant $_SERVER['IP'] = $_SERVER['REMOTE_ADDR']; ca risque de donner une nouvelle valeur à la variable $_SERVER['IP'] à chaque fois que quelqu'un clique, non?

Et j'arrive pas à retrouver où sont stockées les variables superglobales dans phpmyadmin, ca doit être dans information_schema mais je ne trouve pas.. :euh:
Édité le 04/02/2012 à 19:38:01 par jcooleman
Hors ligne Yalio # Posté le 04/02/2012 à 20:06:20
Do you want a salad?
Avatar

Les superglobales ne sont pas stockées dans une base SQL, ce sont des variables auto-générées par PHP.

Par contre, je n'avais pas regardé tout code en détail, le coup du REMOTE_ADDR me paraissant tellement évident. :euh:

Il faut donc enregistrer l'IP ! Là, tu la mets dans une variable. Or, les variables, sauf exception (variables de session) sont détruites à la fin de l'exécution du script. Insères donc l'IP dans la table.
D'autre part, pour faire ta requête, il faut utiliser la méthode exec, query étant utilisée uniquement pour l'affichage. :-°

Deux trois ressources utiles et méconnues
Google, le guide du zCode, lebonforfait.fr (topic) et d'autres à venir.

« Oubliez les versions dépassées des navigateurs. Les supporter, c'est retarder leur disparition ». de warpShadow.
Image utilisateur Même Clint Eastwood le savait !
 
Hors ligne jcooleman # Posté le 05/02/2012 à 09:48:01

Ok je pensais que les superglobales étaient enregistrées indéfiniment donc j'en avais déduis qu'elles étaient forcement enregistrées dans mysql.

Okay je pensais bien que j'allais devoir passer à un enregistrement des IP dans la table de toutes façons.

En ce qui concerne exec/query, les deux fonctionnent alors pourquoi vaut-il mieux utiliser exec?


En tout cas, merci ;)
Édité le 05/02/2012 à 09:48:34 par jcooleman
Hors ligne maxima # Posté le 05/02/2012 à 09:58:33
C’est pas faux.
Avatar

Études : Lycée du Parc - Lyon

Tu utilises celle que tu veux. D'après la doc, exec retourne retourne le nombre de lignes affectées par la requête, alors que query renvoie un PDOStatement (donc les données reçues).

Donc exec est plutôt à utiliser pour un INSERT, UPDATE ou DELETE, et query pour un SELECT.
Édité le 05/02/2012 à 09:59:59 par maxima
Hors ligne jcooleman # Posté le 05/02/2012 à 13:13:36

Okay merci j'avais regardé la doc, mais j'imagine que l'intérêt d'utiliser correctement exec/query c'est une question de performances.

Tant qu'on y est, j'ai eu un petit souci en gérant ma table qui conserve les adresses IP. Je vous montre seulement le petit bout de code qui m'embête :
--> Je veux vérifier que l'adresse IP du mec qui a cliqué n'est pas déjà listée dans la table. Et si ce n'est pas le cas, alors le compteur est incrémenté et l'adresse IP du mec est répertoriée dans la table.

J'étais parti sur un truc pas compliqué dans ce genre-là :

Code : PHP
1
2
3
4
5
6
7
$reponse = $bdd->query('SELECT Adresse_IP FROM article_5 ORDER BY id DESC'); 
	while($donnees = $reponse->fetch()) {
		if  ($donnees['Adresse_IP'] != $_SERVER['REMOTE_ADDR']) {
			$bdd->exec("UPDATE articles SET compteur_article = compteur_article +1 WHERE id=5");
			$bdd->exec("INSERT INTO article_5 (Adresse_IP) VALUES('$_SERVER[REMOTE_ADDR]')"); // ne faites pas attention à l'absence de guillemets pour REMOTE_ADDR
			}
	}


Sauf que ca marche pas puisque le while compare l'adresse IP avec les autres adresses IP prises une par une, donc ma condition est remplie tout le temps ^^. Je voudrais vérifier que $_SERVER['REMOTE_ADDR'] n'est jamais présent dans la colonne Adresse_IP et ensuite envoyer mes requêtes UPDATE et INSERT. Je suis sûr qu'il existe une solution probablement assez simple mais je ne la connais pas et ne sait pas trop comment la googler! :D
Édité le 05/02/2012 à 13:14:42 par jcooleman
Hors ligne maxima # Posté le 05/02/2012 à 17:41:35
C’est pas faux.
Avatar

Études : Lycée du Parc - Lyon

Code : SQL
1
SELECT COUNT(*) FROM Adresse_IP WHERE Adresse_IP="xx.xx.xx.xx"


Avec une jolie requête préparée.
Hors ligne jcooleman # Posté le 05/02/2012 à 21:57:26

Si j'ai bien compris, ma requête préparée doit renvoyer FALSE (ou une erreur) si l'adresse IP n'est pas répertoriée dans le tableau. Et si elle est déjà répertoriée alors ca me renverra le numéro de la ligne (donc un entier).
Alors jme suis dis qu'il suffisait de vérifier que la réponse n'était pas un nombre pour savoir quand l'adresse IP n'était pas répertoriée.

Du coup j'ai utilisé la requête préparée en testant avec une adresse IP qui n'existe pas (10007) et normalement ca aurait dû me renvoyer FALSE ou une erreur (en tout cas, pas un entier). Sauf que ca ne marche pas.

Code : PHP
1
2
3
4
5
$reponsedeux = $bdd->prepare("SELECT COUNT(*) FROM article_5 WHERE Adresse_IP = '10007'");
if (is_nan($reponsedeux)) {
	$bdd->exec("UPDATE articles SET compteur_article = compteur_article +1 WHERE id= '$selected_article'");
	$bdd->exec("INSERT INTO article_5 (Adresse_IP) VALUES('$_SERVER[REMOTE_ADDR]')");
	}



Je pensais que la réponse de la requête était récupérée dans $reponsedeux mais peut-être que je me suis trompé..

NB : Désolé de rammer comme ca, mais je suis déjà pas top en PHP et en plus ca fait un bon moment que j'y ai pas touché à part pour des requêtes simples.
Hors ligne maxima # Posté le 06/02/2012 à 00:26:39
C’est pas faux.
Avatar

Études : Lycée du Parc - Lyon

Mouais, bah va relire le tuto de M@teo21.

- Tu ne sais pas du tout utiliser les requêtes préparées ;
- PDO::prepare (ou PDO::query) renvoie .. un PDOStatement, tu ne peux pas faire un is_nan. Il faut jouer avec des fetch() ou autre. Le plus simple ici étant de faire un fetchColumn(), qui renvoie la colonne 0 de la ligne 0: c'est donc la valeur du COUNT(*).

Tuto PHP / MySQL
Doc PDO sur php.net
Édité le 06/02/2012 à 00:27:56 par maxima
Hors ligne jcooleman # Posté le 06/02/2012 à 13:28:30 Message supprimé pour le motif suivant : Cette réponse a été supprimée par l'utilisateur.
Hors ligne fabieniserois # Posté le 06/02/2012 à 15:47:20
Avatar

Études : BTS IG Grenoble

Salut , voilà un petit tuto (en anglais certes , mais très bien expliqué et compréhensible si tu comprends pas l'anglais :D car le code est simple)
http://www.youtube.com/watch?v=z01pMC1k0K4

Développeur Web : PHP / MySQL / CSS /(x)HTML / Javascript (+ jQuery)
 
Hors ligne demonskiller974 # Posté le 06/02/2012 à 16:10:56
Avatar

Salut , tu enregistre les personnes qui ont déjà clické par adresse IP , donc , si je click et que je change d'adresse IP ( VPN, proxy ... ) je peux reclicker autant de fois que je veux ?

PHP/SQL HTML/CSS JS JAVA C
100% 100% 3% 5% 100%
Intermédiaire Intermédiaire Novice Novice Intermédiaire

Un clavier AZERTY en vaux deux ...
 
Hors ligne jcooleman # Posté le 08/02/2012 à 10:35:36

Citation
Salut , tu enregistre les personnes qui ont déjà clické par adresse IP , donc , si je click et que je change d'adresse IP ( VPN, proxy ... ) je peux reclicker autant de fois que je veux ?


En théorie, tu peux cliquer autant de fois que tu veux tant que tu changes d'adresses IP. Donc avec un VPN et en switchant d'IP avant chaque clic, tu peux en effet accumuler du "like". Evidemment, s'il y avait eu des comptes sur ce site, j'aurai controlé le "like" relativement aux sessions (un compte = un "like", mais on peut toujours créer de nouveaux comptes aussi ^^).



Citation
Salut , voilà un petit tuto (en anglais certes , mais très bien expliqué et compréhensible si tu comprends pas l'anglais car le code est simple)
http://www.youtube.com/watch?v=z01pMC1k0K4


Merci mais j'ai tout fini mon code, il me manque que la fin pour la vérification de l'adresse IP. Mais j'ai regardé et il passe justement par les sessions, donc je suis pas sûr que ca puisse m'aider :/
Édité le 08/02/2012 à 10:38:40 par jcooleman
Hors ligne demonskiller974 # Posté le 08/02/2012 à 14:29:56
Avatar

Tu peux ajouter une session pour chaque utilisateur ( visiteur ) et contrôler ( un like par session ) : a chaque connexion sur le site une session est crée . Ton like ne sera tout de même pas optimal ...

PHP/SQL HTML/CSS JS JAVA C
100% 100% 3% 5% 100%
Intermédiaire Intermédiaire Novice Novice Intermédiaire

Un clavier AZERTY en vaux deux ...
 
Hors ligne jcooleman # Posté le 08/02/2012 à 15:06:24

Citation
Tu peux ajouter une session pour chaque utilisateur ( visiteur ) et contrôler ( un like par session ) : a chaque connexion sur le site une session est crée . Ton like ne sera tout de même pas optimal ...


Ce serait un peu crado et je devrais mettre fin à la session quand la page est fermée : donc les gens pourraient recliquer en revenant sur la page (sauf en les identifiant avec leur IP, ce qui revient à faire la même chose que ce que j'avais prévu mais en plus compliqué xD).

Bon du coup, j'ai réglé mon petit problème, je pensais qu'il fallait que j'utilise le PREPARE comme proposé plus haut mais, allez savoir pourquoi, ca ne marche qu'avec un QUERY. Si l'IP est déjà dans la table, ca me renvoie "1". Si l'IP n'existe pas encore ca me renvoie "0".
Ca pourra peut-être servir à quelqu'un, voilà la solution :

Code : PHP
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
$reponse = $bdd->query("SELECT COUNT(*) FROM ".$table_name." WHERE Adresse_IP = '$_SERVER[REMOTE_ADDR]'");
	$donnees = $reponse->fetchColumn();
	if ($donnees > 0) {
	}
	
	else {
	$bdd->exec("UPDATE articles SET compteur_article = compteur_article +1 WHERE id= '$selected_article'");
	$bdd->exec("INSERT INTO ".$table_name." (Adresse_IP) VALUES('$_SERVER[REMOTE_ADDR]')");

		}


J'ai encore une petite question rapide : les IP sont enregistrées dans une table de données à deux colonnes, par article. J'imagine qu'il serait préférable que je fasse une seule enorme table de données à quatre colonnes pour tout les articles. J'imagine qu'une seule grosse table de données est plus efficiente pour le serveur, ca semblerait logique mais en réalité je n'en sais rien!
Ma question est donc : Vaut-il mieux plein de tables de données légères ou une seule énorme table de données?

EDIT
J'ai fais une version avec une seule table :
Code : PHP
1
2
3
4
5
6
7
8
9
$reponse = $bdd->query("SELECT COUNT(*) FROM likes WHERE Adresse_IP = '$_SERVER[REMOTE_ADDR]' AND Type_billet = '$type_billet'");
	$donnees = $reponse->fetchColumn();
	if ($donnees > 0) {
	}
	
	else {
	$bdd->exec("UPDATE articles SET compteur_article = compteur_article +1 WHERE id= '$selected_article'");
	$bdd->exec("INSERT INTO likes (Adresse_IP, Type_billet) VALUES('$_SERVER[REMOTE_ADDR]', '$type_billet')");
		}
Édité le 08/02/2012 à 16:27:08 par jcooleman
Hors ligne demonskiller974 # Posté le 08/02/2012 à 17:46:57
Avatar

Citation : jcooleman

Ce serait un peu crado et je devrais mettre fin à la session quand la page est fermée : donc les gens pourraient recliquer en revenant sur la page (sauf en les identifiant avec leur IP, ce qui revient à faire la même chose que ce que j'avais prévu mais en plus compliqué xD).

Et pourquoi mettre fin à la session ?
Tu peux simplement créer une session sur la page de like , et ne jamais la détruire , elle restera en mémoire , et sera supprimé après un certain temps automatiquement .

PHP/SQL HTML/CSS JS JAVA C
100% 100% 3% 5% 100%
Intermédiaire Intermédiaire Novice Novice Intermédiaire

Un clavier AZERTY en vaux deux ...
 

Retour au forum "PHP" ou à la liste des forums

Pour accéder à cette section
Connectez-vous !
connexion_rpx


Lire aussi