Trier un Array php

Résolu
Bonjour,

Pour chaque enregistrement de ma base de données, j'ai une date sous la forme "01 MAR 2014".
Dans mon script, je la transforme sous la forme 20140301, ce qui va me permettre d'afficher mes enregistrements par date ASC ou DESC.
Cette transformation, je la fait dans une boucle WHILE pour tous les enregistrements.
Comment afficher ensuite le résultat (issu de l'Array) ?

Merci.

14 réponses

  1. Contributeur
    function cmp($a, $b)
    {
        return strcmp($a["date_mariage"], $b["date_mariage"]);
    }
    
    usort($array, "cmp");


    essaie ça.
    1. Salut,

      Juste une petite remarque :
      C'est dommage d'utiliser PHP pour trier ton tableau alors que la base de donnée permet de le faire de manière beaucoup plus rapide et plus optimisée. Il te suffit d'enregistrer la date en base de données avec un champ DATE ou TIMESTAMP.
      1. OK ! Mais la base existe déjà et comprend plus de 50000 enregistrements.
        J'avais pensé rajouter uner colonne et y transformer les dates qui existent déjà sous plusieurs formes. Mais çaz devient une vrai machine à gaz si on doit modifier une date (écrite dans l'ancien système)
    2. Merci, mais je ne sais pas trop quoi prendre.
      Un enregistrement comprend "id, num_indiv, nom, prénom, nom_conjoint, prenom_conjoint, num_indiv_conjoint, date_mariage, lieu_mariage".
      Et je veux afficher mon résultat en fonction de date_mariage.
      1. Je vois pas trop ce que tu veux dire ............. !!!
        J'avais plutôt pensé à un truc du genre sort().
        1. ThEBiShOp, j'ai appliqué ta méthode, ou plutôt essayé :

          $select = 'SELECT * FROM mariage_ville WHERE SUBSTRING(date_mariage, -4) >= "1600" AND SUBSTRING(date_mariage, -4) <= "1650"';  
          $result = mysql_query($select,$link) or die ('Erreur : '.mysql_error() );
          ///****je transforme date_matiage pour le traitement****
          $date_marg = explode(" ", $date_mariage);
          ..........
          $date_mariage = ("$date_marg[2]$date_marg[1]$date_marg[0]");
          ///**** fin de transformation****

          function cmp($a, $b)
          {
          return strcmp($a["date_mariage"], $b["date_mariage"]);
          }

          usort($date_mariage, "cmp");

          echo '<table>';
          while($row = mysql_fetch_array($result))
          { ..........
          echo '<td width="152">'.$row['date_mariage'].'</td>'; .......
          }

          Et là, j'ai le message : Warning: usort() [function.usort]: The argument should be an array

          Merci de m'aider encore .........
          1. Contributeur
            Il manque des parties non ?

            Tu ne fais pas de mysql_fetch_array ou mysql_fetch_assoc ?
        2. Si, je l'ai mis dans la boucle "While". Mais faut peut-être le mettre avant ?
          J'ai essayé cela :
          $select = 'SELECT * FROM mariage_ville WHERE SUBSTRING(date_mariage, -4) >= "1600" AND SUBSTRING(date_mariage, -4) <= "1650"';  $result = mysql_query($select,$link) or die ('Erreur : '.mysql_error() );
          $row = mysql_fetch_array($result);
          ///****je transforme date_matiage pour le traitement****
          $date_marg = explode(" ", $date_mariage);..........
          $date_mariage = ("$date_marg[2]$date_marg[1]$date_marg[0]");
          ///**** fin de transformation****
          $date_mariage = array("'.$row['id'].'", "'.$row['indiv'].'", "'.$row['nom'].'", "'.$row['prenom'].'", "'.$row['date_mariage'].'");
          sort($date_mariage);
          echo $date_mariage; exit;
          echo '<table>';
          foreach ($date_mariage as $key => $val)
          {
          echo '<tr bgcolor="#CCCCCC" align="center" id="tr1" onclick="afficherCouleur(this)">'; //surlignage
          echo '<td width="242">'$date_mariage[2]'</td>';
          echo '<td width="198">'$date_mariage[3]'</td>';
          echo '<td width="152">'$date_mariage[4]'</td>';
          echo '</tr>';
          }
          echo '</table>';
          Mais j'ai le message Parse error: syntax error, unexpected T_ENCAPSED_AND_WHITESPACE, expecting T_STRING or T_VARIABLE or T_NUM_STRING sur la ligne $date_mariage = array.......
          1. Contributeur
            C'est normal, il n'y a aucune raison de concaténer à cet endroit, tu n'es pas en train de construire une chaine, mais un tableau.

            Tu n'as pas de while sur ton mysql_fetch_array ?
        3. J'ai déconcaténé :
          $date_mariage = array("$row['id']", "$row['indiv']", "$row['nom']", "$row['prenom']", "$row['date_mariage']");
          Et j'ai rajouté le while après le select :
          $select = 'SELECT * FROM mariage_ville WHERE SUBSTRING(date_mariage, -4) >= "1600" AND SUBSTRING(date_mariage, -4) <= "1650"'; 	
          $result = mysql_query($select,$link) or die ('Erreur : '.mysql_error() );
          while ($row = mysql_fetch_array($result))
          { .................
          Mais j'ai toujours le même message ....................
          1. Contributeur
            $date_mariage = array($row['id'], $row['indiv'], $row['nom'], $row['prenom'], $row['date_mariage']);
        4. Ca avance ..................
          Pour mon select, je fais :
          $select = 'SELECT nom,prenom,date_mariage,lieu_mariage,nom_cj,prenom_cj FROM mariage_ville WHERE SUBSTRING(date_mariage, -4) >= "1600" AND SUBSTRING(date_mariage, -4) <= "1650"'; 	
          $result = mysql_query($select,$link) or die ('Erreur : '.mysql_error() );
          while ($row = mysql_fetch_array($result))
          { .....................
          Puis
          ...............
          $date_mariage = array($row['nom'], $row['prenom'], $row['date_mariage'], $row['lieu_mariage'], $row['nom_cj'], $row['prenom_cj']);
          sort($date_mariage[2]);
          echo '<table>';
          foreach ($date_mariage as $key => $val)
          {
          echo '<tr bgcolor="#CCCCCC" align="center" id="tr1" onclick="afficherCouleur(this)">'; //surlignage
          echo '<td width="242">'.$date_mariage[0].'</td>'; //nom
          echo '<td width="198">'.$date_mariage[1].'</td>'; //prénom
          echo '<td width="152">'.$date_mariage[2].'</td>'; //date_mariage
          echo '<td width="152">'.$date_mariage[3].'</td>'; //lieu_mariage
          Et j'ai le message Warning: sort() expects parameter 1 to be array, string given ........
          Si j'essaye avec "usort", "ksort" ou autre, j'ai :
          Warning: Wrong parameter count for usort() ................
          1. Contributeur
            Par pitié, arrête de mettre des fragments de code, mets tout, sinon je n'arriverai jamais à comprendre tes erreurs.
        5. Oupps, désolé !

          $select = 'SELECT nom,prenom,date_mariage,lieu_mariage,nom_cj,prenom_cj FROM mariage_ville WHERE SUBSTRING(date_mariage, -4) >= "1600" AND SUBSTRING(date_mariage, -4) <= "1650"'; 	
          $result = mysql_query($select,$link) or die ('Erreur : '.mysql_error() );
          while ($row = mysql_fetch_array($result))
          {
          //**** Modification $date_mariage
          $date_marg = explode(" ", $date_mariage);

          if (!empty($date_marg[1]) && empty($date_marg[2])) //*** s'il n'existe que "mois an"
          {
          if ($date_marg[0] == "JAN") { $date_marg[0] = '01'; }
          if ($date_marg[0] == "FEB") { $date_marg[0] = '02'; }
          if ($date_marg[0] == "MAR") { $date_marg[0] = '03'; }
          if ($date_marg[0] == "APR") { $date_marg[0] = '04'; }
          if ($date_marg[0] == "MAI") { $date_marg[0] = '05'; }
          if ($date_marg[0] == "JUN") { $date_marg[0] = '06'; }
          if ($date_marg[0] == "JUL") { $date_marg[0] = '07'; }
          if ($date_marg[0] == "SEP") { $date_marg[0] = '09'; }
          if ($date_marg[0] == "OCT") { $date_marg[0] = '10'; }
          if ($date_marg[0] == "NOV") { $date_marg[0] = '11'; }
          if ($date_marg[0] == "DEC") { $date_marg[0} = '12'; }
          if (!empty($date_marg[0]) && empty($date_marg[1]))//*** s'il n'existe que "an"
          { $date_mariage = ("$date_marg[0]0000"); }
          //**** Fin Modification $date_mariage

          $date_mariage = array($row['nom'], $row['prenom'], $row['date_mariage'], $row['lieu_mariage'], $row['nom_cj'], $row['prenom_cj']);
          usort($date_mariage[2]);
          echo '<table>';
          foreach ($date_mariage as $key => $val)
          {
          echo '<tr bgcolor="#CCCCCC" align="center" id="tr1" onclick="afficherCouleur(this)">';
          echo '<td width="242">'.$date_mariage[0].'</td>'; //nom
          echo '<td width="198">'.$date_mariage[1].'</td>'; //prénom
          echo '<td width="152">'.$date_mariage[2].'</td>'; //date_mariage
          echo '<td width="152">'.$date_mariage[3].'</td>'; //lieu_mariage
          echo '<td width="152">'.$date_mariage[4].'</td>'; //nom_cjt
          echo '<td width="152">'.$date_mariage[5].'</td>'; //prénom_cjt
          echo '</tr>';
          }
          echo '</table>';
          }
          1. Contributeur
            y'a pas mal de trucs qui vont pas.

            pour transformer ta date utilise plutôt ça :
            date("Ymd", strtotime($date));

            Une seule ligne.

            Ensuite, ta date se trouve dans $date_mariage ? Cette variable sort de nulle part non ?
            Dans ton while, ta date sera dans $row['date_mariage'], c'est ça que tu dois utiliser dans la fonction que j'ai cité plus haut.

            Ensuite, tu écrases ton éventuelle variable $date_mariage, comme tu fais :
            $date_mariage = array(...):

            A chaque fois, tu écrases ce qui pouvait se trouver à l'intérieur, donc une fois que tu vas sortir de ton while, tu auras un $date_mariage avec une seule ligne.
            Un sort n'a donc aucun sens, surtout que tu veux faire un sort sur la 2ème ligne de tableau, qui devrait être un tableau également pour que ça ait un sens.

            Enfin bref...

            Un truc de ce genre devrait mieux marcher :

            $select = 'SELECT nom,prenom,date_mariage,lieu_mariage,nom_cj,prenom_cj FROM mariage_ville WHERE SUBSTRING(date_mariage, -4) >= "1600" AND SUBSTRING(date_mariage, -4) <= "1650"';
            $result = mysql_query($select, $link) or die('Erreur : ' . mysql_error());
            $tableau = array();
            
            while ($row = mysql_fetch_array($result)) {
                //**** Modification $date_mariage
                $date = date("Ymd", strtotime($row['date_mariage']));
                //**** Fin Modification $date_mariage
            
                // je mets dans le tableau toutes les infos de ma ligne, je mets comme clé la date au format numérique, pour simplifier le tri.
                $tableau[$date] = $row;
            }
            
            ksort($tableau);
            echo '<table>';
            foreach ($tableau as $key => $val) {
                echo '<tr bgcolor="#CCCCCC" align="center" id="tr1" onclick="afficherCouleur(this)">';
                echo '<td width="242">' . $val['nom'] . '</td>';  //nom
                echo '<td width="198">' . $val['prenom'] . '</td>'; //prénom
                echo '<td width="152">' . $val['date_mariage'] . '</td>'; //date_mariage
                echo '<td width="152">' . $val['lieu_mariage'] . '</td>'; //lieu_mariage
                echo '<td width="152">' . $val['nom_cjt'] . '</td>'; //nom_cjt
                echo '<td width="152">' . $val['prénom_cjt'] . '</td>'; //prénom_cjt
                echo '</tr>';
            }
            echo '</table>';


            j'ai pas testé dans le détail, étant donné que je n'ai pas les données de ta bdd, mais le principe devrait fonctionner...
        6. Bonjour ThEBiShOp,
          La solution que tu me proposes n'est pas ce que je cherche ...........
          Je ne peux faire
          $date = date("Ymd", strtotime($row['date_mariage']));
          car la date peut être de différent format (01 JAN 1501, Avant JAN 1501, 1501, ..............). Donc, cette date n'est pas dans un format adéquate ! C'est pour cela que je fait une transformation.
          Et $date_mariage est le résultat de cette transformation.
          Dans ma boucle while, je commence par faire un explode pour tester chaque élément de la date_mariage.
          while ($row = mysql_fetch_array($result)) 
          {
          //**** Modification $date_mariage
          $date_marg = explode(" ", $row['date_mariage']);

          if ($date_marg[0] == "Avant" || $date_marg[0] == "Après" || $date_marg[0] == "Vers" || $date_marg[0] == "Entre")
          { $date_marg_bis = ("$date_marg[1] $date_marg[2] $date_marg[3]"); }
          else
          { $date_marg_bis = ("$date_marg[0] $date_marg[1] $date_marg[2]"); }

          $date_marg = explode(" ", $date_marg_bis);

          if ($date_marg[2] == "JAN") { $date_marg[2] = '01'; }
          if ($date_marg[2] == "FEB") { $date_marg[2] = '02'; }
          if ($date_marg[2] == "MAR") { $date_marg[2] = '03'; }
          if ($date_marg[2] == "APR") { $date_marg[2] = '04'; }
          ..................
          $date_mariage = ("$date_marg[2]$date_marg[1]$date_marg[0]");//$date_mariage modifiée et prête à être triée
          }
          J'ai testé mes variables $date_marg et $date_mariage, c'est bon !
          Mon problème maintenant, c'est de trier le résultat de la boucle while et de l'afficher ........... !?
          1. Contributeur
            Tu as au moins pris la peine de tester ce que je t'ai proposé ?
            Tu connais l'utilité de la fonction strtotime ?

            Je relis ton code un peu plus haut.
            au début de ton while :
            $date_marg = explode(" ", $date_mariage);

            $date_mariage qui sort de nulle part, et maintenant, tu me dis que tu as :
            $date_marg = explode(" ", $row['date_mariage']);
            que j'ai proposé dans mon code...

            Tu te moquerais pas un petit peu de moi ? :)
        7. La fonction strotime permet de lire un format date autre que le notre. hez moi, il n'y a pas de format quelconque.
          Quand j'avais écrit $date_marg = explode(" ", $date_mariage);, j'avais oublié le $row ........... Désolé !
          Si je teste ton code, sur 10000 enregistrements, il en affiche 2 (pourquoi ces 2 là ? je ne sais pas).
          Et je ne me permettrais pas de me moquer de toi ! Tu prends déjà de la patience pour t'occuper de mes difficultés ........... !
          1. Contributeur
            la fonction STRTOTIME va permettre de convertir une chaine de caractère en une date, elle peut comprendre pas mal de format différents, j'ai fais quelques tests et pour une date du genre "12 JAN 2013" et "JAN 2013", aucun soucis par contre si tu as juste l'année, ça ne fonctionne pas parfaitement, à la limite, tu peux juste traiter cette exception et utiliser strtotime pour le reste, ça simplifierait ton code, non ?
            Ou bien je n'ai pas compris les différents formats que tu peux avoir.

            Après, dans le détail, je ne peux pas te donner un code qui va fonctionner parfaitement du premier coup étant donné que je n'ai pas tes données en BDD, mais dans le principe, ça devrait fonctionner, après, à toi d'adapter légèrement ce qu'il faut.
        8. Voilà où j'en suis
          ................................
          $date_mariage = ("$date_marg[2]$date_marg[1]$date_marg[0]"); //date_mariage modifié, prête à être triée
          }
          $final = ("$row[nom] $row[prenom] $date_mariage $row[lieu_mariage] $row[nom_cj] $row[prenom_cj]");

          echo $final;

          } //fin de la boucle while
          Le echo $final affiche mes résultas, mais faudrait piouvopir les trier sur $final[2] !!!! Comment ????
          1. Contributeur
            $final, c'est une chaine de caractère que tu construis de façon assez hasardeuse, ce n'est pas un tableau, il sera donc absolument impossible de faire un quelconque tri dessus.

            Si tu veux faire un tableau, dans lequel tu mettras toutes tes lignes pour ensuite faire un éventuel tri dessus, tu dois l'initialiser avant ton while, et ajouter une nouvelle ligne à chaque tour dans ton while.

            Tiens... mais... on dirait que c'est exactement ce que j'ai fait dans le code que j'ai pris le temps de faire y'a 2 jours et que tu as considéré qu'il ne correspondait pas à ce que tu attendais !
        9. Ca y est, j'y suis arrivé. En me servant largement de ton script, et en y incluant mes modifications sur la date ..............
          Je te remercie de m'avoir aidé, et de ta patience !!!!
          A ++
          1. Contributeur
            de rien ^^

            bon courage