IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

PHP & Base de données Discussion :

Changer l'ordre d'une liste [MySQL]


Sujet :

PHP & Base de données

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Inscrit en
    Juin 2008
    Messages
    34
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 34
    Par défaut Changer l'ordre d'une liste
    Bonjour à tous,

    Ça fait un bon moment que je relis mon code, que je cherche sur Google et je ne trouve pas la réponse à mon problème.

    Je veux écrire un code qui me permette de réorganiser les éléments d'une liste grâce à une entrée dans une base SQL qui s'appelle user_order.

    PHP lit la BDD et organise ma liste par ordre croissant de user_order.
    Il reste à ajouter ou enlever 1 à ce user_order pour le faire descendre ou monter et à donner l'ancien user_order à l'annonce qui suit (si je descend) ou qui précède (si je monte) pour ne pas avoir deux fois le même user_order.

    Voici mon code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    <?php
    // J'inclus un fichier qui contient le code pour se connecter à la base
    	include ('./includes/tools.php');
    // Je récupère le sens du changement (up ou down) dans une variable
    	$ordre = $_GET['ordre'];
    // Je récupère l'id de l'annonce à monter ou descendre
    	$id_annonces = $_GET['annonce'];
    // Je récupère son ordre d'origine dans la BDD
    	$order_brut = mysql_query("SELECT user_order FROM bakovitz_annonces WHERE id_annonces = '$id_annonces'");
    	$order_net = mysql_fetch_array($order_brut);
    // Je crée la nouvelle valeur que j'insérerai dans user_order plus loin dans le cas ou je descend l'annonce
    	$down = $order_net['user_order'] + 1;
    // Idem mais pour la monter
    	$up = $order_net['user_order'] - 1;
    	$ancien = $order_net['user_order'];
     
    	switch($ordre) {
    // Si on descend l'annonce on ajoute 1 à son user_order
    		case 'down' : mysql_query("UPDATE bakovitz_annonces SET user_order = '$down' WHERE id_annonces = '$id_annonces'");
    // On enlève 1 à son voisin du dessous pour qu'il prenne sa place
    		mysql_query("UPDATE bakovitz_annonces SET user_order = '$ancien' WHERE user_order = '$down'"); break;
    // L'inverse si on monte
    		case 'up' : mysql_query("UPDATE bakovitz_annonces SET user_order = '$up' WHERE id_annonces = '$id_annonces'");
    		mysql_query("UPDATE bakovitz_annonces SET user_order = '$ancien' WHERE user_order = '$up'"); break;
    	}
    ?>
    Le problème c'est que quand j'exécute le code (avec 2 annonces) seule l'annonce voisine change de user_order. J'ai donc deux annonces avec le même user_order.
    Si je veux monter celle du bas, seule sa voisine du haut change...

    Je suis sûr que c'est un truc évident de syntaxe ou quoi parce que la logique de mon code me paraît juste.

    Merci par avance pour vos éventuelles réponses !

  2. #2
    Membre Expert

    Homme Profil pro
    Inscrit en
    Janvier 2004
    Messages
    1 249
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : Finance

    Informations forums :
    Inscription : Janvier 2004
    Messages : 1 249
    Par défaut
    il faut modifier TOUTES les lignes qui changent d'ordre, donc quelque chose comme :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    // deplacement de l'item a la position $order vers le haut (donc vers $order - 1):
    // * L'element a ($order -1) passe a la position $order
    // * L'element a $order passe a la position ($order - 1)
     
    // Utilisation d'un index "temporaire" pour deplacer l'element courant
    UPDATE table
    SET order = -1
    WHERE order = $order;
     
    // Deplacement de l'element precedent vers le bas
    UPDATE table
    SET order  = order + 1 // ou = $order si tu preferes ^^
    WHERE order = $order - 1
     
    // Positionnement de l'element courant a la place de l'element précédent
    UPDATE table
    SET order = $order - 1
    WHERE order = -1
    Idem pour le deplacement vers le bas.

  3. #3
    Membre averti
    Inscrit en
    Juin 2008
    Messages
    34
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 34
    Par défaut
    Merci Fladnag mais je ne suis pas sûr de bien comprendre.

    Tu me proposes une solution directement en SQL au lieu de faire faire les calculs par PHP c'est ça ?

    Je ne comprend pas non plus la raison de l'existence de l'index temporaire puisque s'il n'est pas le premier de la liste il chevauchera à un moment sur un autre non ?

    Et enfin (ça fait beaucoup !) j'aurais bien aimé avoir un commentaire sur le code que j'avais écris dans un but didactique, pour pas dire oui oui sans comprendre.


  4. #4
    Membre Expert Avatar de Djakisback
    Profil pro
    Inscrit en
    Février 2005
    Messages
    2 023
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 2 023
    Par défaut
    En tout cas ici il me semble qu'il y a clairement un problème :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    case 'down' : mysql_query("UPDATE bakovitz_annonces SET user_order = '$down' WHERE id_annonces = '$id_annonces'");
    // On enlève 1 à son voisin du dessous pour qu'il prenne sa place
    		mysql_query("UPDATE bakovitz_annonces SET user_order = '$ancien' WHERE user_order = '$down'"); break;
    Car la première ligne définit l'order à $down de ta news.
    Mais ta 2e ligne modifie toutes les news qui ont l'order = $down donc à priori l'annonce que tu viens de modifier va être modifiée une 2e fois ? à moins que je me plante ^^ je crois qu'il faudrait que t'inverses les 2 requêtes.

  5. #5
    Membre Expert

    Homme Profil pro
    Inscrit en
    Janvier 2004
    Messages
    1 249
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : Finance

    Informations forums :
    Inscription : Janvier 2004
    Messages : 1 249
    Par défaut
    Quel que soit l'ordre dans lequel tu execute les requetes, la 2eme va forcement modifier :
    * L'element qui n'a pas bougé
    * L'element qui a été mis a la nouvelle place avec la 1ere requete.

    C'est pour ca que j'utilise un "index temporaire" dans ma solution.

    Il faudrait pouvoir executer les 2 requetes UPDATE en meme temps pour faire ca en une seule requete, avec 2 ca me parait difficile... a moins de trouver une fonction qui pour X associe X-1 et pour X-1 associe X, et encore je ne suis pas sur que l'UPDATE fonctionnera correctement (et ca doit dépendre des bases de données)

    C'est le meme probleme que pour inverser 2 variables :

    $a=1;
    $b=2;

    comment faire en sorte que $a==2 et $b==1 ? en utilisant la variable temporaire $c
    $c=$a;
    $a=$b;
    $b=$c;

    (y a d'autres solutions pour ce cas là, mais c'était pour l'exemple ;o)

  6. #6
    Membre Expert Avatar de Djakisback
    Profil pro
    Inscrit en
    Février 2005
    Messages
    2 023
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 2 023
    Par défaut
    Je ne comprends pas trop l'utilisation de l'index temporaire.
    Ceci devrait suffire non ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    $current = 4;
    case 'down' :
    if($current > 0)	{
    	mysql_query("UPDATE bakovitz_annonces SET user_order = user_order + 1 WHERE user_order = $current - 1");
    	mysql_query("UPDATE bakovitz_annonces SET user_order = user_order - 1 WHERE id_annonces = '$id_annonces'");
    }
     
    break;
    Il faut aussi ajouter des tests d'extrêmes dans tes switch, tu ne peux pas décrémenter l'ordre d'une news s'il est inférieur à 1, ni incrémenter l'ordre s'il il est égal à max(ordre). Il faut aussi penser à recréer les suites d'ordres lorsque tu supprimes une news pour garder un état cohérent ^^

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [AJAX] Sauvegarder l'ordre d'une liste après modification par javascript
    Par Ashgenesis dans le forum Général JavaScript
    Réponses: 0
    Dernier message: 07/02/2008, 15h54
  2. Changer l'ordre d'une liste
    Par ethno dans le forum Général JavaScript
    Réponses: 3
    Dernier message: 03/01/2008, 12h19
  3. changer Option Selected d'une Liste
    Par Link45 dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 24/05/2007, 12h04
  4. Réponses: 2
    Dernier message: 05/06/2006, 17h51
  5. Réponses: 1
    Dernier message: 20/04/2006, 09h17

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo