Tri des elements

Messages postés
414
Date d'inscription
lundi 19 juillet 2004
Statut
Membre
Dernière intervention
23 septembre 2014
- - Dernière réponse : cs_alexscott
Messages postés
55
Date d'inscription
vendredi 28 février 2003
Statut
Membre
Dernière intervention
10 novembre 2006
- 10 nov. 2006 à 05:05
Bonjour

   J'ai une liste d'éléments dans ma base de données. Ils disposent d'un champs ordre qui me permet de pouvoir les afficher dans un certain ordre, mais surtout de pouvoir modifier cet ordre.

Voici le code qui me permet de modifier cet ordre : 
if ($val < $ord) {
   $query = mysql_query("SELECT id_famille, ordre FROM famille WHERE ordre>='".$val."' AND ordre<'".$ord."';");
   while ($tmp = mysql_fetch_array($query))
      mysql_query ("UPDATE famille SET ordre='".($tmp['ordre']+1)."' WHERE id_famille='".$tmp['id_famille']."';");
} elseif ($val > $ord) {
   $query = mysql_query("SELECT id_famille, ordre FROM famille WHERE ordre>'".$ord."' AND ordre<='".$val."';");
   while ($tmp = mysql_fetch_array($query))
      mysql_query ("UPDATE famille SET ordre='".($tmp['ordre']-1)."' WHERE id_famille='".$tmp['id_famille']."';");
}
mysql_query("UPDATE famille SET ordre='".$val."' WHERE id_famille='".$id."';");

 - $ord représente la valeur actuelle de ordre pour l'élément que l'on veut modifier.
 - $val représente la valeur que l'on veut lui donner
 - $id est l'identifiant de cet élément

Ce code modifie tous les éléments contenus dans la table alors qu'il ne devrait modifier que ceux sélectionnés dans la requête. Les valeurs passées ($ord, $val, $id) sont les bonnes.
Si quelqu'un comprend où est l'erreur....

Merci d'avance
Afficher la suite 

4 réponses

Messages postés
12336
Date d'inscription
mardi 10 février 2004
Statut
Modérateur
Dernière intervention
30 juillet 2012
27
0
Merci
Salut,

ça modifie tout les ordres des id_famille séléctionnés...

ton code fait quoi, il devrait faire quoi ? donne des exemples de données et de valeurs pour $val et $ord stp...

In a dream, I saw me, drop dead... U was there, U cried... It was just a dream, if I die, U won't cry, maybe, U'll be happy

Mon site (articles sur la programmation et programmes)
Commenter la réponse de coucou747
Messages postés
414
Date d'inscription
lundi 19 juillet 2004
Statut
Membre
Dernière intervention
23 septembre 2014
0
Merci
Le principe est le suivant :  Il y a une liste d'éléments et à côté de chaque élément il y a un <select> qui contient la valeur du champs ordre de l'élément (valeur sélectionnée par défaut) ansi que les valeurs du champs ordre des autres éléments.
Cette valeur est différente pour chaque élément puisque c'est en fonction de celle-ci que les éléments vont être triés pour l'affichage.
Imagnons qu'il y ait 4 enregistrements dans la base de données :
 - element1 dont le champs ordre a pour valeur 1
 - element2 dont le champs ordre a pour valeur 2
 - element3 dont le champs ordre a pour valeur 3
 - element4 dont le champs ordre a pour valeur 4

Les éléments seronts affichés dans cette ordre car je fais un tri croissant par rapport au champs ordre.

Si je veux maintenant que element2 s'affiche en dernier, il faut que son champs ordre soit le plus grand.
Je change la valeur dans le <select> et je met 4. Le onChange de mon select appelle alors mon premier code avec :
 - $id = element2
 - $ord = 2 (valeur actuelle du champs ordre de element2)
 - $val = 4 (valeur que je veux lui donner)

Il faut alors que le champs ordre de element3 passe à 2 et que celui de element4 passe à 3. Par contre celui de element1 n'a pas à changer.
Je devrai obtenir :
 - element1 dont le champs ordre a pour valeur 1
 - element3 dont le champs ordre a pour valeur 2
 - element4 dont le champs ordre a pour valeur 3
 - element2 dont le champs ordre a pour valeur 4
Au lieu de ça j'obtiens : 
 - element1 dont le champs ordre a pour valeur 0
 - element3 dont le champs ordre a pour valeur 2
 - element4 dont le champs ordre a pour valeur 3
 - element2 dont le champs ordre a pour valeur 4

element1 a aussi été modifié mais il devrai pas

Je sais pas si j'ai été clair mais j'ai fai de mon mieux
Commenter la réponse de cs_ov3rdoze
Messages postés
55
Date d'inscription
vendredi 28 février 2003
Statut
Membre
Dernière intervention
10 novembre 2006
0
Merci
<?
//fonction de callback pour un tri a 1 cle
function mytri($a, $b)
{
global $mytritype;

if ($a[$mytritype] == $b[$mytritype])
return(0);

return(($a[$mytritype] > $b[$mytritype]) ? 1 : -1);
}

//fonction de callback pour un tri a 2 cles
function mytri2($a, $b)
{
global $mytritype1;
global $mytritype2;

if ($a[$mytritype1] == $b[$mytritype1])
{
if ($a[$mytritype2] == $b[$mytritype2])
return(0);

return(($a[$mytritype2] > $b[$mytritype2]) ? 1 : -1);
}

return(($a[$mytritype1] > $b[$mytritype1]) ? 1 : -1);
}

//met l'element qui etait a la place $ord a la place $val et decale les autres elements
function echange($tab, $ord, $val)
{
if ($val < $ord)
{
for($i = 0; $i < count($tab); $i++)
{
if(($tab[$i]['ordre'] >= $val) && ($tab[$i]['ordre'] < $ord))
$tab[$i]['ordre'] += 1;
}
}
elseif ($val > $ord)
{
for($i = 0; $i < count($tab); $i++)
{
if(($tab[$i]['ordre'] <= $val) && ($tab[$i]['ordre'] > $ord))
$tab[$i]['ordre'] -= 1;
}
}

$tab[$ord]['ordre'] = $val;

return($tab);
}

#MAIN
global $mytritype;
global $mytritype1;
global $mytritype2;

$tab = array(
array(
array( 'ID_CL' => 1232, 'ID_PC' => 1857, 'code' => 'XE206', 'libelle' => 'legume', 'famille' => 'ENDIVE', 'ordre' => 0 ),
array( 'ID_CL' => 1232, 'ID_PC' => 2090, 'code' => 'XEFP510MIX', 'libelle' => 'legume', 'famille' => 'ENDIVE', 'ordre' => 1 ),
array( 'ID_CL' => 1232, 'ID_PC' => 1864, 'code' => 'EFP1KGA', 'libelle' => 'fruits', 'famille' => 'fraise', 'ordre' => 2 ),
array( 'ID_CL' => 1232, 'ID_PC' => 1868, 'code' => 'EFP500NT', 'libelle' => 'divers', 'famille' => 'soupe', 'ordre' => 3 )
),
array(
array( 'ID_CL' => 1240, 'ID_PC' => 1857, 'code' => 'XE206', 'libelle' => 'legume', 'famille' => 'ENDIVE', 'ordre' => 0 ),
array( 'ID_CL' => 1240, 'ID_PC' => 2090, 'code' => 'XEFP510MIX', 'libelle' => 'legume', 'famille' => 'ENDIVE', 'ordre' => 1 ),
array( 'ID_CL' => 1240, 'ID_PC' => 1864, 'code' => 'EFP1KGA', 'libelle' => 'fruits', 'famille' => 'fraise', 'ordre' => 2 ),
array( 'ID_CL' => 1240, 'ID_PC' => 1868, 'code' => 'EFP500NT', 'libelle' => 'divers', 'famille' => 'soupe', 'ordre' => 3 )
)
);

print_r($tab);

//dans une boucle si on part du principe qu'on fait le meme changement d'ordre pour tous les sous-tableaux
foreach($tab as &$val)
$val = echange(&$val, 0, 2);
//print_r($tab);

//ensuite on souhaite retrier les tableaux en fonction de l'ordre
$mytritype = 'ordre';
foreach($tab as &$val)
usort(&$val, 'mytri');
//print_r($tab);

//ensuite on souhaite retrier les tableaux en fonction de l'ID_PC
$mytritype = 'ID_PC';
foreach($tab as &$val)
usort(&$val, 'mytri');
//print_r($tab);

//evidemment si ton but et de "perdre une dimension il suffit de faire"
$newtab = array();
foreach($tab as &$val)
$newtab = array_merge($newtab, $val);
print_r($newtab);

$mytritype = 'ID_PC';
usort($newtab, 'mytri');
print_r($newtab);

//Ha et que tu perdes ou non une dimension si tu veux faire un tri a plusieurs cles
//je le fais pour 2 car pour 3 c'est pareil en plus complique
//ca vaut peut-etre le coup d'utiliser array_multisort d'ailleurs dans ce cas la
//enfin c'est chiant array_multisort je te ferais une demo pour trier avec les deux
//memes cles juste apres

$mytritype1 = 'ordre';
$mytritype2 = 'ID_CL';
usort($newtab, 'mytri2');
print_r($newtab);

//alors pour faire ce dernier tri que je viens de faire avec array_multisort
//il faut extraire les colonnes qui nous interessent
//je fais des SORT_DESC pour qu'on puisse observer le fait que le tri a ete effectue
$key1 = array();
$key2 = array();

foreach($newtab as $val)
{
$key1[] = $val[$mytritype1];
$key2[] = $val[$mytritype2];
}

array_multisort($key1, SORT_NUMERIC, SORT_DESC, $key2, SORT_NUMERIC, SORT_DESC, $newtab);
print_r($newtab);

//voila sinon je vois pas comment faire pour utiliser le multisort sur ton tableau de depart
//et si je travaille sur le tableau bout par bout c'est parce que ce que si on nomme comme ca
//les differentes composantes de ton tableau
// A( B_0( C_0, C_1, C_2, C_3), B_1(C_0, C_1, C_2, C_3))
//si tu fais directement un tri sur A tu pourras juste changer l'ordre des B et pas leur contenu//a moins de demander le tri des C_x dans la fonction de callback
//ou de faire un truc un peu bizarre avec array_walk_recursive

//voila voila ... sache que j'ai fait tout ca uniquement parce que je me faisais chier mais que
//je n'avais vraiment aucune raison de le faire surtout vu l'entrain que tu as mis a lire la doc//mais je me fais pas de soucis, si tu veux tirer partie des quelques trucs que j'ai montre tu
//vas surement etre oblige de lire la doc qu'on t'a conseille et revient pas nous demander
//ce qu'est une fonction de callback ...

//D'ailleurs dans les fonctions de callback j'utilise des test == et > qui ont pas forcement
//beaucoup de sens pour des chaines de caracteres enfin de toute facon les fonctions de callbacks
//ca sert justement a adapte le test a faire en fonction des donnees a traiter


//voila sinon je tenais a remercier ov3rdoze a qui j'ai pris son code qui fonctionne bien
//http://www.phpcs.com/infomsg_TRI-ELEMENTS_839480.aspx#2
?>
Commenter la réponse de cs_alexscott
Messages postés
55
Date d'inscription
vendredi 28 février 2003
Statut
Membre
Dernière intervention
10 novembre 2006
0
Merci
merde je me suis trompe de page le message precedent n'a rien a faire ici :s
c'etait pour http://www.phpcs.com/infomsg_INVERSION-TRI-TABLEAU-MULTIDIMENTIONNEL_838861.aspx#8
donc ici je voulais juste dire que ton code fonctionne bien et que ca n'a pas l'air d'etre une erreur d'implementation peut-etre serait-ce une erreur de manque de precision en mysql. tu devrais essayer de voir le nombres de lignes affectees par tes update : http://fr2.php.net/manual/fr/function.mysql-affected-rows.php
Commenter la réponse de cs_alexscott