Précédent   Forum des professionnels en informatique > PHP > Langage > Fonctions
Fonctions Forum d'entraide sur les fonctions PHP. Avant de poster -> FAQ fonctions et Sources diverses
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 02/07/2008, 10h39   #1
Invité de passage
 
Inscription : juin 2008
Messages : 28
Détails du profil
Informations forums :
Inscription : juin 2008
Messages : 28
Points : 2
Points : 2
Par défaut [Tableaux] Tri tableau multidimensionnel en fonction d'une de ses colonnes

Bonjour, j'espère que quelqu'un pourra m'aider car je suis désespéré...

Voila j'explique le probleme: je voudrai réaliser le tri d'un tableau multidimensionnel en fonction d'une colonne de ce dernier. J'ai essayé en vain avec les fonctions php, notamment multisort_array, mais je ne parviens a ne trier que la colonne en question et non tout le tableau, ou alors j'ai du mal utiliser la fonction....

voici mon tableau , chaque colonne contient une liste de valeur:

Code :
Array ( [id] => Array ( [0] => 66656 [1] => 38607 [2] => 41478 [3] => 68722 ) [submitter] => Array ( [0] => villeruptimmo_athomelor [1] => unicorn_athome [2] => dfiest_athome [3] => dargent_athomelor ) [offerstate] => Array ( [0] => active [1] => active [2] => active [3] => active ) [insdate] => Array ( [0] => 2005-05-12 10:28:40 [1] => 2005-06-08 09:07:20 [2] => 2005-07-21 18:20:25 [3] => 2005-09-14 15:30:59 ) [numChamb] => Array ( [0] => 6 [1] => 3 [2] => 8 [3] => 4 ) [country] => Array ( [0] => France [1] => France [2] => France [3] => France ) [region] => Array ( [0] => Meurthe et Moselle [1] => Moselle [2] => Moselle [3] => Meurthe et Moselle ) [immotype] => Array ( [0] => 13 [1] => 13 [2] => 18 [3] => 1 ) [commune] => Array ( [0] => Villerupt [1] => Rettel [2] => METRICH [3] => Longwy ) [garage] => Array ( [0] => -1 [1] => 1 [2] => 1 [3] => -1 ) [prix] => Array ( [0] => 220000 [1] => 195000 [2] => 466000 [3] => 345000 ) [surface] => Array ( [0] => 0.00 [1] => 140.00 [2] => 354.00 [3] => 350.00 ) )

Moi par exemple ce que je voudrai c'est par exemple trier chaque ligne en fonction par exemple des ID croissants. J'ai alors tenté:

Code :
array_multisort($tableModifie['id'], SORT_ASC , SORT_NUMERIC);
Mai ca ne trie que la colonne tri et les autres n'ont pas été modifiées...

Sinon quelqu'un aurait il une autre idée afin de trier un tel tableau sachant que j'ai besoin du tri et de l'ordre...

je vous remercie d'avance
coeurdange est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 02/07/2008, 11h07   #2
Membre Expert
 
Homme
Inscription : janvier 2004
Messages : 1 238
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations professionnelles :
Secteur : Finance

Informations forums :
Inscription : janvier 2004
Messages : 1 238
Points : 1 421
Points : 1 421
Il faut lui donner toutes les colonnes que tu souhaites trier... donc :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?php
$aTab = array ('id' => array ('0' => '66656' ,'1' => '38607' ,'2' => '41478' ,'3' => '68722' ),'submitter' => array ('0' => 'villeruptimmo_athomelor' ,'1' => 'unicorn_athome' ,'2' => 'dfiest_athome' ,'3' => 'dargent_athomelor' ),'offerstate' => array ('0' => 'active' ,'1' => 'active' ,'2' => 'active' ,'3' => 'active' ),'insdate' => array ('0' => '2005-05-12 10:28:40' ,'1' => '2005-06-08 09:07:20' ,'2' => '2005-07-21 18:20:25' ,'3' => '2005-09-14 15:30:59' ),'numChamb' => array ('0' => '6' ,'1' => '3' ,'2' => '8' ,'3' => '4' ),'country' => array ('0' => 'France' ,'1' => 'France' ,'2' => 'France' ,'3' => 'France' ),'region' => array ('0' => 'Meurthe et Moselle' ,'1' => 'Moselle' ,'2' => 'Moselle' ,'3' => 'Meurthe et Moselle' ),'immotype' => array ('0' => '13' ,'1' => '13' ,'2' => '18' ,'3' => '1' ),'commune' => array ('0' => 'Villerupt' ,'1' => 'Rettel' ,'2' => 'METRICH' ,'3' => 'Longwy' ),'garage' => array ('0' => '-1' ,'1' => '1' ,'2' => '1' ,'3' => '-1' ),'prix' => array ('0' => '220000' ,'1' => '195000' ,'2' => '466000' ,'3' => '345000' ),'surface' => array ('0' => '0.00' ,'1' => '140.00' ,'2' => '354.00' ,'3' => '350.00' ));
 
echo '<pre>';
print_r($aTab);
 
array_multisort(	$aTab['id'], SORT_ASC , SORT_NUMERIC,
					$aTab['submitter']
					$aTab['offerstate'],
					$aTab['insdate'] ,
					$aTab['numChamb'] ,
					$aTab['country'], 
					$aTab['region'] ,
					$aTab['immotype'] ,
					$aTab['commune'] ,
					$aTab['garage'] ,
					$aTab['prix'],
					$aTab['surface']
);
 
echo '<hr><pre>';
print_r($aTab);
 
?>
__________________
PHP :
Regle n°1 : mysql_query(...), mysql_connect(...) et mysq_select_db(...) doivent EN DEBUG etre suivies de or die(mysql_error()); (mais jamais en production)
Regle n°2 : Mieux encore : mysql_query($requete) or die("$requete<br/>".mysql_error());
Regle n°3 : echo '<pre>';var_dump($var);echo '</pre>'; affiche le contenu et le type d'une variable.
Publiez vos textes de fantasy et de science-fiction sur http://www.cercledefaeries.com/concours/
Fladnag est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 02/07/2008, 13h13   #3
Invité de passage
 
Inscription : juin 2008
Messages : 28
Détails du profil
Informations forums :
Inscription : juin 2008
Messages : 28
Points : 2
Points : 2
Par défaut AIDE 2

Merci beaucoup pour votre réponse, j'ai esssayé et ca marche bien, mais j'ai un autre soucis, et j'ai tenté de le résoudre en vain aussi.....

Vous l'avez surement compris, la méthode de tri est appelé pour trier le tableau lorsque l'on a sélectionné un tri et/ou un ordre. par contre il faut que je fasse ce tri sur la colonne en question (faire un test) et lister toutes les autres colonnes dans les paramétrés de la fonction. Je vois pas comment faire car c'est dynamique. Je pensais faire une variable qui contiendrais tous les tableaux des autres colonnes de cette manière:


Code :
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
27
28
29
30
31
// Test sur l'ordre sélectionné
if($_POST['param_ordre']=="ASC")
{
	$ordre=SORT_ASC;
}else if($this->view->param_ordre=="DESC")
{	
	$ordre=SORT_DESC;		
}		
 
// Test sur le tri sélectionné
if($_POST['param_tri']=="ASC")
{
	$tri='id';
}
 
// selection de toutes les colonnes autres que celle concernée par le tri
$lestableau=$tableModifie['submitter'].",".
$tableModifie['offerstate'].",".
$tableModifie['insdate'].",".
$tableModifie['numChamb'].",".
$tableModifie['country'].",". 
$tableModifie['region'].",".
$tableModifie['immotype'].",".
$tableModifie['commune'].",".
$tableModifie['garage'].",".
$tableModifie['prix'].",".
$tableModifie['surface'];
 
array_multisort($tableModifie[$tri], $ordre , SORT_NUMERIC,
					$lestableau
);
Mais quand je lance ceci ca me dit que les 4eme paramètre n'est pas un tableau
coeurdange est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 02/07/2008, 13h27   #4
Membre Expert
 
Homme
Inscription : janvier 2004
Messages : 1 238
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations professionnelles :
Secteur : Finance

Informations forums :
Inscription : janvier 2004
Messages : 1 238
Points : 1 421
Points : 1 421
ok.
En effet, comme ca, ca ne peux pas marcher.

Le mieux je pense est de gérer la liste des colonnes dans un autre tableau ;o)

Par exemple :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
$tri=$_POST['colonneTri'];
 
$listeColonnes=array('id', 'prix', 'surface', 'region',...); // 12 elements
 
unset($listeColonnes[array_search($listeColonnes[$tri])]); // on "supprime" la colonne correspondant au tri
// une autre solution :
// $listeColonnes=array_flip($listeColonnes);
// unset($listeColonnes[$tri]);
// $listeColonnes=array_flip($listeColonnes);
 
array_multisort(
  $tab[$tri], ..., ..., // on va trier selon la colonne du tri
  $tab[$listeColonnes[0]], // on ajoute toutes les autres colonnes
  $tab[$listeColonnes[1]],
  $tab[$listeColonnes[2]],
  $tab[$listeColonnes[3]],
...
  $tab[$listeColonnes[9]],
  $tab[$listeColonnes[10]] // on va jusqu'a l'index 10 car la liste commence a 0, et on a enlevé un element, donc on a bien 11 elements en tout + la colonne de tri
);
Il y aurait d'autres methodes basées sur eval, qui permet d'executer le code php écrit dans une chaine construite grace a des concaténations comme tu le fait, mais c'est beaucoup moins propre ;o)
__________________
PHP :
Regle n°1 : mysql_query(...), mysql_connect(...) et mysq_select_db(...) doivent EN DEBUG etre suivies de or die(mysql_error()); (mais jamais en production)
Regle n°2 : Mieux encore : mysql_query($requete) or die("$requete<br/>".mysql_error());
Regle n°3 : echo '<pre>';var_dump($var);echo '</pre>'; affiche le contenu et le type d'une variable.
Publiez vos textes de fantasy et de science-fiction sur http://www.cercledefaeries.com/concours/
Fladnag est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 02/07/2008, 13h50   #5
Invité de passage
 
Inscription : juin 2008
Messages : 28
Détails du profil
Informations forums :
Inscription : juin 2008
Messages : 28
Points : 2
Points : 2
Merci encore pour votre réponse, que je viens de tester,
j'ai une erreur cependant au niveau de la fonction de suppression de la colonne du tri :

j'obtiens les erreurs :

Code :
1
2
3
4
5
Notice: Undefined index: id  
 
// ET
 
Wrong parameter count for array_search()
J'ai d'ailleurs tester directement dans la fonction sans récupérer le _POST en faisant :
Code :
unset($listeColonnes[array_search($listeColonnes['id'])])
mais sans succès.

J'ai trouvé la solution :

Code :
unset($listeColonnes[array_search($tri,$listeColonnes)]); // on "supprime" la colonne correspondant au tri
Par contre en faisant un print_r() du nouveau tableau je me suis rendu compte que le la suppression de la colonne du tri, entraine la suppression de l'indice et le tableau possède alors un trou..esty il possible de redéfinir le tableau pour qu'il n'y ait plus ce "trou";
coeurdange est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 02/07/2008, 14h39   #6
Membre Expert
 
Homme
Inscription : janvier 2004
Messages : 1 238
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations professionnelles :
Secteur : Finance

Informations forums :
Inscription : janvier 2004
Messages : 1 238
Points : 1 421
Points : 1 421
oui, en effet, j'ai écrit n'importe quoi dans array_search ;o)

Pour éviter le "trou", on peut faire ensuite :

Code :
$listeColonnes = array_values($listeColonnes);
ca va réindexer les elements.
__________________
PHP :
Regle n°1 : mysql_query(...), mysql_connect(...) et mysq_select_db(...) doivent EN DEBUG etre suivies de or die(mysql_error()); (mais jamais en production)
Regle n°2 : Mieux encore : mysql_query($requete) or die("$requete<br/>".mysql_error());
Regle n°3 : echo '<pre>';var_dump($var);echo '</pre>'; affiche le contenu et le type d'une variable.
Publiez vos textes de fantasy et de science-fiction sur http://www.cercledefaeries.com/concours/
Fladnag est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 02/07/2008, 15h31   #7
Invité de passage
 
Inscription : juin 2008
Messages : 28
Détails du profil
Informations forums :
Inscription : juin 2008
Messages : 28
Points : 2
Points : 2
Par défaut AIDE FINALE

Voila c'est bon j'ai réussi à faire ce que je voulais, merci beaucoup.

Je voudrais pour terminer vous poser une question car vous m'avez l'air d'être quelqu'un qui connait très bien le php.

Alors voila je vous explique : le tableau crée précédemment est utilisé pour lister un contenu volumineux provenant d'une bdd elle aussi volumineuse (plus de 190 tables). Ne désirant pas surcharger MYSQL et le serveur, j'ai désiré faire la requête 1 seule fois: je mets alors les résultats de cette dernière dans un tableau (le fameux tableau initial :-) ). Puis je le mets en cache.

Si je sélectionne un tri particulier et/ou un ordre je récupère le cache et je fais le tri établi précédemment. tout fonctionne c super....

Mais je voudrais faire un système de pagination...alors voila la question et je voudrais avoir votre avis: qu'est il préférable de faire afin de réduire la consommation des ressources au niveau MYSQL et du serveur, et ainsi de réduire le temps de traitement??

1) mettre en cache (dans le tableau initial) tous les résultats (pouvant comptabiliser des milliers de lignes), puis rappeler les résultats (de 10 en 10 par exemple) dans chaque page, et remettre en cache pour un tri éventuel.

ou

2) refaire la requête initiale a chaque foi que l'on change de page (avec la clause LIMIT), puis mettre en cache les résultats.

Par la même occasion, le choix du tri et de l'ordre doit il, à votre avis, se faire sur tous les résultats, ou simplement sur ceux de la page en cours??

Merci beaucoup pour votre aide
coeurdange est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 02/07/2008, 16h06   #8
Membre Expert
 
Homme
Inscription : janvier 2004
Messages : 1 238
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations professionnelles :
Secteur : Finance

Informations forums :
Inscription : janvier 2004
Messages : 1 238
Points : 1 421
Points : 1 421
Bon... quelques points deja :

* Un tri MYSQL sera toujours plus rapide qu'un tri PHP
* PHP est un langage "stateless", donc une fois que la page est chargée, les objets sont détruits... donc pour implementer une notion de "cache" en PHP il faudrait stocker l'infos dans une session... qui a une taille limitée ! Ou dans un fichier... mais le temps d'écriture et d'acces a un fichier n'est pas tres éloigné d'une execution de requete si celle ci est sans jointure et avec une clause where simple.
* Pour le tri global puis pagination ou pour la pagination puis le tri, c'est a voir avec l'utilisateur... en principe il prefere le tri global puis la pagination.

Petite remarque au passage : LIMIT de mysql n'est pas ultra performant hélas ;o) mais il n'y a pas grand chose de mieux pour faire ca.

Vous avez donc 2 possibilités :
A) Récuperer toutes les données en UNE seule fois et les afficher sur la page du navigateur client... ca va etre TRES long (en esperant ne pas depasser le timeout) mais ensuite la pagination et le tri peuvent etre fait... en javascript ! Donc aucune charge serveur.
B) Récuperer les données d'une page avec LIMIT, eventuellement avec un ORDER BY en MYSQL qui vient de l'utilisateur.
Sur la page affichée, le tableau pourra etre retrié "localement" en javascript, sans requete SQL. Par contre, lors de l'affichage de la 2eme page, le tri doit s'effectuer sur la meme colonne que lors de la 1ere requete (sinon on aura des résultats incohérents) a moins que l'utilisateur ait spécifié un autre tri explicitement.

J'avoue que je préfère la 2eme methode. Cela suppose avoir 2 criteres de tri : 1 pour la requete sql et 1 autre pour le javascript.
Pour faire ca, le mieux serait d'avoir :
* Un <select> du genre "Trier par : [.....]" => Requete SQL / Rechargement de page
* des fleches "triangle haut/triangle bas" sur les entetes de chaque colonne du tableau pour retrier au sein de la meme page en javascript.

Si vous ne souhaitez pas implementer du javascript, la pagination avec mysql reste le meilleur moyen, et un 2eme tri en php pour éviter de faire la requete (sur la meme page)... pourquoi pas !

PS : En fait c'est quoi que vous utilisez comme "cache" ?
__________________
PHP :
Regle n°1 : mysql_query(...), mysql_connect(...) et mysq_select_db(...) doivent EN DEBUG etre suivies de or die(mysql_error()); (mais jamais en production)
Regle n°2 : Mieux encore : mysql_query($requete) or die("$requete<br/>".mysql_error());
Regle n°3 : echo '<pre>';var_dump($var);echo '</pre>'; affiche le contenu et le type d'une variable.
Publiez vos textes de fantasy et de science-fiction sur http://www.cercledefaeries.com/concours/
Fladnag est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 03h43.


 
 
 
 
Partenaires

Hébergement Web