[RESOLU] système de classement à partir de points

Eléphanteau du PHP | 34 Messages

29 août 2016, 09:34

Salut,
Sur mon site on peut s'inscrire et donc enregistrer dans la bdd sur une table membre. Dans cette table il y a une ligne points. Cette ligne correspond à une valeur int qui donne le nombre de points que l'utilisateur à gagner en participant à la vie du site.
Voilà la fonction qui attribut les point :

Code : Tout sélectionner

function point($pseudo, $pt) { include('modele/connexion_sql.php'); //on cherche si le pseudo existe $sql = $bdd->prepare('SELECT pseudo FROM membre WHERE pseudo = ?'); $sql->execute(array($pseudo)); $req = $sql->fetch(); if ($req['pseudo']) { //on selectionne le nombre de point $sql = $bdd->prepare('SELECT points FROM membre WHERE pseudo = ?'); $sql->execute(array($pseudo)); $req = $sql->fetch(); //on met tout sous forme de nombre entier $point = (int) $req['points']; $pt = (int) $pt; //on ajoute les points gagner $point += $pt; //on sauve le tout dans la bdd $sql = $bdd->prepare('UPDATE membre SET points = ? WHERE id = ?'); $sql->execute(array($point, $pseudo)); } }
Comment faire pour donner un rang (classement) à l'utilisateur sachant que celui-ci vari tout le temps. Si je clique sur une page "classement" comment faire pour obtenir son rang à ce moment précis ainsi que les utilisateurs (mettons les 5) qui ont plus de points et qui en ont moins. Je suppose qu'il doit exister une méthode avec un peut de bon sql et de php, mais je ne voit pas comment faire quelque chose d'optimisé si il y a beaucoup d’utilisateur.

ynx
Eléphant du PHP | 288 Messages

30 août 2016, 11:37

Salut,

Sur la page "classement", il suffit de faire une requête sql ressemblant à :
SELECT pseudo, points FROM membre ORDER BY points DESC LIMIT 5
Cette requête permet de récupérer la liste des 5 premiers pseudo (et leurs points) ayant le plus de points. Le tri via ORDER BY et la limite de la requête sql permet à celle-ci d'être optimisée et devrait être exécutée très rapidement indépendamment du nombre d'utilisateurs.

Bonne journée,

Eléphanteau du PHP | 34 Messages

30 août 2016, 12:34

Merci, effectivement c'est une bonne solution. En revanche comment faire pour le classement absolut (de tout les joueur, genre 289/4576) comment faire, parceque c'est là que cette méthode pêche.

ynx
Eléphant du PHP | 288 Messages

30 août 2016, 15:42

Pour connaitre le rang d'un utilisateur, on peut utiliser la requête sql suivante :
SELECT COUNT(*) + 1 AS rang FROM membre WHERE points > (SELECT points FROM membre WHERE id = ?)
-> où ? est l'identifiant de l'utilisateur

La sous-requête (SELECT points FROm membre WHERE id = ?) retourne le nombre de points de l'utilisateur spécifié (prenons par exemple 1000 points).
La requête SELECT * FROM membre WHERE points > 1000 retourne la liste des membres qui ont plus de 1000 points.
Il suffit alors de compter le nombre membres qui ont plus de 1000 points pour obtenir le rang de l'utilisateur (avec +1 pour ne pas commencer le premier rang à 0).

Il est nécessaire de vérifier que l'utilisateur existe avant d'utiliser cette requête, sinon celle-ci retournera le rang 1 pour un utilisateur inexistant.

Eléphanteau du PHP | 34 Messages

30 août 2016, 18:11

ça à l'air de fonctionner (je savais même pas qu'on pouvais faire des sous-requêtes !).
JH'ai crée une petite fonction :

Code : Tout sélectionner

<?php function rang($pseudo) { include('modele/connexion_sql.php'); //on cherche si le pseudo existe $sql = $bdd->prepare('SELECT pseudo FROM membre WHERE pseudo = ?'); $sql->execute(array($pseudo)); $req = $sql->fetch(); if ($req['pseudo']) { //on cherche le rang $sql = $bdd->prepare('SELECT COUNT(*) + 1 AS rang FROM membre WHERE points > (SELECT points FROM membre WHERE pseudo = ?)'); $sql->execute(array($pseudo)); $req = $sql->fetch(); $sql = $bdd->query('SELECT COUNT(*) AS nb_membre FROM membre'); $req_membre = $sql->fetch(); return array($req['rang'], $req_membre['nb_membre']); } else { return FALSE; } } ?>

Tongahasina
Invité n'ayant pas de compte PHPfrance

05 nov. 2019, 16:54

Merci =D> =D>