tri dans tableau

Discussion dans 'Web, design' créé par DeScH, 13 Juillet 2006.

Statut de la discussion:
Fermée.
  1. Offline
    DeScH AstaLaVista
    Hello, et oui c'est encore moi avec mes questions de noobs vous me direz :)

    Bon en fait j'ai un tableau qui se présente comme ceci:
    [IMG]

    Je voudrais créer un lien sur catégorie et date, pour me permettre de trier les données selon la méthode voulue.


    Pour le moment mon code se présente comme ceci :

    <table align="center">
    <tr>
    <th>Modifier</th>
    <th>Supprimer</th>
    <th>Titre</th>
    <th>Date</th>
    <th>Cat&eacute;gorie</th>
    </tr>


    <?php
    $retour = mysql_query('SELECT * FROM news ORDER BY categorie DESC');
    while ($donnees = mysql_fetch_array($retour)) /
    {
    ?>

    <tr>
    <td:colere:?php echo '<a href="rediger_news.php?modifier_news=' . $donnees['id'] . '">'; ?>Modifier</a:colere:/td>
    <td:colere:?php echo '<a href="liste_news.php?supprimer_news=' . $donnees['id'] . '">'; ?>Supprimer</a:colere:/td>
    <td:colere:?php echo stripslashes($donnees['titre']); ?:colere:/td>
    <td:colere:?php echo date('d/m/Y', $donnees['timestamp']); ?:colere:/td>
    <td:colere:?php echo stripslashes($donnees['categorie']); ?:colere:/td>
    </tr>

    <?php
    }

    ?>
    </table>

    Pourriez-vous m'aider? Merci :=)
    DeScH, 13 Juillet 2006
    #1
  2. Offline
    Leaf pentoboules (h)
    Bon hé ben j'vais encore une fois essayer de répondre à ma façon simpliste hein :-D

    La c'est simple (enfin si j'ai bien compris ce que tu demandes) :
    Serval, une idée pour améliorer peut-être ? :=)
    Leaf, 13 Juillet 2006
    #2
  3. Offline
    *Serval Elite
    han il savait que j'allais passer :D

    C'est nickel, je rajouterai juste une sécurité pour le GET (quoi qu'ici, cela n'est pas vraiment nécessaire car "tri" n'est pas utilisé dans la requête SQL ;))


    Dans cet exemple, la valeur de $_GET['tri'] ne DOIT être que cat ou date.

    on va donc faire ce qu'on appelle une white list pour vérifier si la valeur du paramètre tri est bien cat ou date.

    Je propose pour faire simple :

    $query='SELECT * FROM news';
    if(isset($_GET['tri']))
    {
    $white = Array("cat", "date");
    if (in_array($_GET['tri'], $white))
    {
    $tri = $_GET['tri'];
    if($tri=='cat')
    {
    $query=$query." ORDER BY categorie";
    }
    if($tri=='date')
    {
    $query=$query." ORDER BY timestamp";
    }
    }
    else
    {
    echo $message_erreur_a_definir;
    }
    }
    $query=$query." DESC";
    mysql_query($query);




    Sinon, dans ce cas-ci, on n'a que 2 solutions possibles, mais si il y en avait plus (à partir de 3, 4), un switch serait mieux que des if ;)

    petit truc : $query=$query." ORDER BY timestamp";
    peut aussi s'écrire $query.="ORDER BY timestamp";

    sinon vu qu'ici je vérifie d'abord si le tri est dans le tableau, on peut utiliser ceci :
    $query.= $tri=='cat' ? " ORDER BY categorie" : " ORDER BY timestamp";

    (si il y a besoin que j'explique cette syntaxe, demandez ;))






    donc au final cela donnerait :

    $query='SELECT * FROM news';
    if(isset($_GET['tri']))
    {
    $white = Array("cat", "date");
    if (in_array($_GET['tri'], $white))
    {
    $tri = $_GET['tri'];
    $query.= $tri=='cat' ? " ORDER BY categorie" : " ORDER BY timestamp";
    }
    /* ceci est optionnel moi perso je le mettrais pas
    else
    {
    echo $message_erreur_a_definir;
    }
    */
    }
    $query=$query." DESC";
    mysql_query($query);


    Enfin bref c'était bien ton truc Leaf :)
    *Serval, 13 Juillet 2006
    #3
  4. Offline
    *Serval Elite
    en me relisant je me rends compte que ca fait vraiment parano de faire une white list alors que tri n'est pas utilisé dans la requete...


    Mais j'ai pris l'habitude de le faire aussi souvent que possible pr les paramètres passés en GET et je ne penses pas qu'un excès de sécurité ne puisse faire du mal :p (enfin sauf si ca ralentit tout le brol :D)
    *Serval, 13 Juillet 2006
    #4
  5. Offline
    Leaf pentoboules (h)
    Lool, c'est vrai, mais bon j'ai pas rajouté de conditions dans le sens ou si la valeur de $_GET['tri'] est inexistante, nulle ou que $_GET['tri'] n'est pas défini, ça allait juste faire la requête normale sans le "ORDER BY..." :-D
    Leaf, 13 Juillet 2006
    #5
  6. Offline
    Leaf pentoboules (h)
    Jle savais en plus, mais j'savais plus si c'était .= ou =. donc j'ai préféré être sur :-D
    Han je demande alors :cool:
    Leaf, 13 Juillet 2006
    #6
  7. Offline
    *Serval Elite
    $query.= $tri=='cat' ? " ORDER BY categorie" : " ORDER BY timestamp";

    Alors on va découper ca en morceau...

    Ceci concatener un string à $query ( $query.= ) en fonction d'une condition ( $tri=='cat' ? ).

    Si cette condition est vérifiée, le string qu'on concatène est " ORDER BY categorie", sinon c'est ce qu'il y a après les : donc " ORDER BY timestamp"


    Cela équivaut donc à faire


    if ($tri == 'cat')
    {
    $query .= " ORDER BY categorie";
    }
    else
    {
    $query .= " ORDER BY timestamp";
    }




    J'adore cette syntaxe, surtout parce que la moitié des gens ne la comprennent pas :D




    sinon pour le test tu as raison ;)
    (han je t'ai owné à curveball :p)
    *Serval, 14 Juillet 2006
    #7
  8. Offline
    Calvin80 Elite
    juste qques précisions sur cette synatxe :
    1 - elle devient illisible en cas d'abus
    2 - elle est moins efficace (iveau performance) qu'un if / else
    Calvin80, 14 Juillet 2006
    #8
  9. Offline
    *Serval Elite
    ah bon ?
    plus lent à executer ?

    C'est bon à savoir pour les gros scripts de fou :p
    *Serval, 14 Juillet 2006
    #9
  10. Offline
    Calvin80 Elite
    oui legerement plus lente
    comme les
    "
    sont plus lents que les
    '

    comme les
    $x=$y=0;

    sont plus lents que les
    $x=0;$y=0;

    etc... (ceci dit la différence de lenteur justifie-t-elle la différence de moyen.. pas sûr) :-'
    Calvin80, 14 Juillet 2006
    #10
  11. Offline
    Leaf pentoboules (h)
    D'accord :-D
    Mais bon, j'garderai quand même le bon vieux if / else, ça m'a l'air beaucoup plus lisible (mais bon c'est ptet une question d'habitude en fait :) )

    T'as aucun mérite, j'suis nul jte l'avais dit :p
    Leaf, 14 Juillet 2006
    #11
  12. Offline
    DeScH AstaLaVista
    Mezrci de vos propositions
    En fait ça marche quand je clique sur catégorie ou date
    mais si je charcge la page, ca met:
    Warning: mysql_fetch_array(): supplied argument is not a valid MySQL result resource

    EDIT: j'ai viré $query=$query." DESC";

    et la ca marche. merci de votre aide les gars :)
    DeScH, 14 Juillet 2006
    #12
  13. Offline
    *Serval Elite
    ouep Leaf au début aussi j'avais du mal avec cette syntaxe, mais tu t'y habitues vite ;)

    Sinon Desch, met le DESC dans les 2 closes ORDER BY ;)

    car si tu ne passe rien en paramètre et que tu as un DESC sans ORDER BY, normal que ca aille pas :D
    *Serval, 14 Juillet 2006
    #13
  14. Offline
    DeScH AstaLaVista
    Ouai j'avais fait ça finalement :p
    Tiens tant qu'on y est: pour monter ou descendre un article, vous sauriez pas m'expliquer? :)
    J'imagine qu'il faut faire un truc du meme genre et remplacer l'id de l'article du dessus par celui du dessous nan?
    DeScH, 14 Juillet 2006
    #14
  15. Offline
    *Serval Elite
    ca dépend un peu de ce que tu veux faire

    soit l'admin monte ou descend un article pour tout le monde (donc les gens le verront affichés tous dans cet ordre là), soit c'est l'utilisateur qui fait son tri

    Donc le premier cas, il faut trier la liste par ID et quand l'admin veut changer l'ordre et qu'il clique sur "monter" par exemple, l'article change d'id (-1) et l'article qui était au dessus change aussi (+1)


    Dans le second cas, il faut faire un tableau avec un id aussi pour chacun ;)




    Attention avec le premier cas lors de la suppresion d'un article, pas oublier de décrémenter l'id de tous les éléments qui le suivaient ;)
    *Serval, 14 Juillet 2006
    #15
  16. Offline
    Leaf pentoboules (h)
    Je crois qu'il veut dire l'admin monte ou descend un article pour qu'ils apparaissent dans un ordre différent quand on affiche tous les articles :)
    Si ça peut t'aider personnellement je vois ton truc comme ceci :

    Dans ta partie admin, tu as tout tes articles qui sont affichés et classés par id juste avec leur titre, comme ceci :

    <tr>
    <td>$titre_de_la_news</td>
    <td>
    <a href='../admin/upanddown.php?id=$id&action=1'> + </a> /
    <a href='../admin/upanddown.php?id=$id&action=-1'> - </a>
    </td>
    </tr>


    donc, ce qui donnerait par exemple :
    • Bienvenue sur le site : + / -
    • News à propos de x : + / -
    • News à propos de y : + / -
    • News à propos de z : + / -
    Alors maintenant, sur la page upanddown.php :

    $id=intval($_GET['id']);
    $action=intval($_GET['action']);

    /* tu récupères l'id et ce que tu veux faire de l'article dont tu veux changer la place via le formulaire dans la partie admin par ex ( pas besoin de tester les données vu que c'est toi qui les introduits et pas celui qui surfe sur ton site )*/
    --- tu mets tes variables de connect à ta bdd ---
    if($action==1) {
    $nid=$id++;
    }
    else {
    $nid=$id--;
    }
    $q="UPDATE news SET id=$nid WHERE id=$id";
    $q2="UPDATE news SET id=$id WHERE id=$nid";

    mysql_query($q);
    mysql_query($q2);

    Voila bon j'ai pas testé, mais j'crois que ça devrait marcher même si mon code est un poil tordu à la relecture :oops:

    Serval ( ou quelqu'un d'autre hein ) si t'as une idée lache toi, j'suis pas fier de moi la :-D
    Leaf, 14 Juillet 2006
    #16
  17. Offline
    Calvin80 Elite
    cest le genre de truc qui sent vraiment pas bon ça...
    un id, c'est pas fait pour etre changer. c'est pas le but.

    Si tu veux gerer l'affichage, ajoute un champ "order" dans ta base de donnée

    alter table xxx add order int(11);
    update table xxx set order=id;

    et ensuite, tu joues avec order (comme leaf le suggere)

    Parce sque si ton id est utilisé pour des tables croisés, tu vas rentrer dans un beau borde :dead:
    Calvin80, 14 Juillet 2006
    #17
  18. Offline
    DeScH AstaLaVista
    ok merci je vais essayer :)
    Et encore une petite chose (je susi chiant hein :-D)
    comment faire pour récupérer les articles datant de maximum une semaine. Je ne connais pas les fonctions date en php :-s

    EDIT: fini par trouvé
    $semaine == 3600*24*7;
    $date = time();
    $articles = $date - $semaine;
    $retour = mysql_query("SELECT * FROM news WHERE timestamp <='$articles' ORDER BY id DESC");
    :p
    DeScH, 14 Juillet 2006
    #18
  19. Offline
    *Serval Elite
    d'accord avec Calvin80 concernant les IDs, un autre champ pour l'ordre me parait plus propre ;)


    Sinon ton truc me semble pas trop mal Leaf ;)

    Faudrait juste penser, lors de la suppression d'une news, à décrementer le champ order de toute les news suivante (donc qui ont un order plus grand ;))
    Une bête boucle ;)
    *Serval, 17 Juillet 2006
    #19
  20. Offline
    Calvin80 Elite
    pas besoin de boucle:
    update news set order=order-1 where id>$id
    Calvin80, 17 Juillet 2006
    #20
Statut de la discussion:
Fermée.