Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

[PHP-SQL] affichage de hierarchie

15 réponses
Avatar
pounch
Re,

Visiblement j'avais mal formulé mon post la derniere fois et donc il a
ete refusé par les ops (je ne jette pas la pierre, c'est ma faute :-p)

Donc ce que je voulais c'etait pouvoir afficher le resultat d'une
requete sql qui donnait ceci:
+----------------+
| Parent | Child |
+----------------+
| A | AA |
| A | AB |
| A | AC |
| AA | AAA |
| AA | AAB |
| AB | ABA |
| AAB | AABA |
| B | |
| C | CA |
| C | CB |
+----------------+

J'aimerais pouvoir afficher, grace à PHP (sisi, j'vous jure), la hierarchie:

A
-- AA
-- AAA
-- AAB
-- AABA
-- AB
-- ABA
B
C
-- CA
-- CB

Je ne sais pas comment coder ceci ... dois-je passer par un tableau
alternatif ou grace à mon resultset, je sais le faire directement? ou
alors, dois-je passer par une fonction recursive? (j'aime pas le recursif)

Merci,
Dams

10 réponses

1 2
Avatar
loufoque
Avatar
loufoque
La façon la plus pertinente de gérer des arbres en SQL est la
représentation intervallaire des arborescences.

http://sql.developpez.net/arborescence/
Avatar
John Gallet
pounch wrote:

Re,

Visiblement j'avais mal formulé mon post la derniere fois et donc il a
ete refusé par les ops (je ne jette pas la pierre, c'est ma faute :-p)

Donc ce que je voulais c'etait pouvoir afficher le resultat d'une
requete sql qui donnait ceci:
Bonjour,


ou alors, dois-je passer par une fonction recursive? (j'aime pas le recursif)


Le récursif, comme toujours, bouffe un peu les perfs dès lors qu'on
atteint des quantité importantes d'empilements(tout dépend donc de la
profondeur de l'arbre hiérarchique), mais c'est effectivement le plus
facile à coder dans ce type de représentations hiérarchique simple.
Faire attention aux arguments passés dans la fonction récursive.

Concernant la structure de la table, qui ne relève pas de ce forum mais
de fr.comp.applications.sgbd , c'est toujours pareil, à chaque besoin la
solution qui lui est la plus adaptée, le marteau pilon n'étant pas
nécessairement le meilleur antipuce du marché.

a++;
JG

Avatar
pounch
Salut,

John Gallet wrote:
Le récursif, comme toujours, bouffe un peu les perfs dès lors qu'on
atteint des quantité importantes d'empilements(tout dépend donc de la
profondeur de l'arbre hiérarchique)


Normalement la profondeur ne devrait pas excéder 7 ou 8.
Donc pour les perfs, ça devrait aller.

, mais c'est effectivement le plus
facile à coder dans ce type de représentations hiérarchique simple.
Faire attention aux arguments passés dans la fonction récursive.


Mon probleme est principalement le coding car ...

Je recois un resultat sql et donc, je ne connais pas l'ordre des noeuds.
Remarquez que si j'encode correctement tout d'un coup, je devrais avoir
un ordre logique. Apres une mise à jour, ça commence à devenir plus
aléatoire.

Donc je pars du principe que je lis un noeud au hasard.
Logiquement, un noeud n'a pas de pere et donc on est sur une racine, il
a un pere mais pas de fils, donc on est sur une feuille et fatalement,
il reste le cas ou il a un pere et un/plusieurs fils.

Je voudrais remplir un tableau en respectant la hierarchie et en
utilisant le recursif.

J'ai trouvé un bout de code qui permet de créer statiquement les
tableaux mais le gars commence par les fils (logique) et remonte ainsi
son arborescence. Voir son code ci-dessous:

function aff_tab($tab){
echo "<ul>n";
foreach($tab AS $cle => $val){
if( !is_array($val) ){
echo "<li>[$cle] => $val</li>n";
}else{
echo "<li>[$cle] => n";
aff_tab($val);
echo "</li>n";
}
}
echo "</ul>n";
}

/* Exemple DE BASE */
$z = array("POO", "MySQL");

$a = array("objet", "classes");
$b = array("séquentiel", "bibliothèque de fonctions");
$c = array("script", "Vive Php5 !", $z);

$d = array("Java", $a);
$e = array("C", $b);
$f = array("Php", $c);

$g = array($e, $d, $f);

aff_tab($g);


Mon probleme est donc de construire ces tableaux à partir d'un noeud
aleatoire ...

$rs = mysql_query("select ...");
while ($node = mysql_fetch_array($rs)) {
// the code here
}


J'ai ete assez clair?

Avatar
270553
oups. lire:

f_enfants($row['enfant']); // là l'enfant devient un parent
^^^^^^^^^

Pierre
Avatar
270553
Bonjour,


Donc ce que je voulais c'etait pouvoir afficher le resultat d'une
requete sql qui donnait ceci:
+----------------+
| Parent | Child |
+----------------+
| AAB | AABA |
| B | |



Je partirais plutôt d'une table dont la structure serait
-parent
-enfant (avec une contrainte d'unicité)
-nom (par exemple)

ce qui te donnerait
+----------------+
| Parent | Child |
| | A <--
| A | AA |
| A | AB |
| A | AC |
| AA | AAA |
| AA | AAB |
| AB | ABA |
| AAB | AABA |
| | B <--
| | C <--
| C | CA |
| C | CB |
+----------------+


Je ne sais pas comment coder ceci ... dois-je passer par un tableau
alternatif ou grace à mon resultset, je sais le faire directement? ou
alors, dois-je passer par une fonction recursive? (j'aime pas le recursif)


pourquoi pas une fonction récursive renvoyant un tableau :


function f_enfants($parent) {
$req="select parent, enfant, nom FROM latable WHERE
parent='$parent' ORDER BY enfant";
$result=mysql_query($req) or die('requête incorrecte');
while ( $row= mysql_fetch_array($result) ) {
$niveau=$tab[$row['parent']]['niveau']+1; // $niveau
servira aux indentations
$tab[$row['enfant']]=array('niveau' => $niveau, 'nom'
=> $row['nom'], 'parent' => $row['parent']);
f_children($row['enfant']); // là l'enfant devient un
parent
}
return($tab);
}

utilisation :
f_enfants(''); //renvoie tout l'arbre
f_enfants('A'); //renvoie la descendance de 'A'

Après tu lis $tab et tu indentes avec $niveau.

A n'utiliser que pour des petits arbres, et attention aux appels en
boucle (éviter par exemple que 'ABA' soit parent de 'A', sinon ...)

J'espère que ça t'aidera,

Pierre

Avatar
loufoque
pierre a dit le 18/02/2005 à 21:32:

pourquoi pas une fonction récursive renvoyant un tableau :


À noter que le récursif casse très vite les performances sur de l'SQL.
D'où la technique que j'ai fournie : pratique, puissante, performante et
dont apparemment tout le monde se fout.

Avatar
Julien PACHET

Mon probleme est principalement le coding car ...



<auto_pub=on>

Contrairement à la solution proposée par Loufoque que j'ai trouvé
particulièrement interessante, j'ai developpé une classe PHP qui
transforme une table 2D comme tu le decris en un format permettant
d'obtenir toutes les infos necessaires sur l'arbre: pere, liste des
ailleuils, enfants, niveau, affichage en mode texte et graphique,
deploiement des noeuds, repliement, etc...
c'est dispo ici:
http://www.phpclasses.org/browse/package/1268.html

<auto_pub=off>

Avatar
Jean Francois Ortolo
Je vous conseille...

- De tout mettre en mémoire vive i.e. une variable indicée ( format à
voir dans n'importe quel bouquin sur les algorithmes d'arbres. )

- De trier la variable indicée de manière à ce que vous puissiez
traverser l'arbre de la manière que vous jugerez bon. ( voir le bouquin
sur les arborescences, je crois que ça s'appelle "level order" pour
votre type d'affichage. )

- De gérer l'affichage avec un algorithme ad hoc, que vous déduirez
des relations entre les positionnements relatifs dans l'affichage des
noeuds de l'arbre, et leurs positions dans l'arbre.

En effet, mettre en mémoire améliore beaucoup les performances SQL,
vous faites seulement un ordre SELECT unique, et vous mettez dans les
variables indicées chaques noeuds et ses caractéristiques éventuellement.

Evidemment, si votre arbre est trop gros pour tenir en mémoire vive,
alors faudra changer votre structure de table(s).

Bien à vous.

Jean Francois Ortolo

--
Visitez mon site entièrement gratuit
donnant des Statistiques et des Historiques Graphiques
sur les Courses de Chevaux:
http://www.ortolojf-courses.com
Avatar
jerome herve
À noter que le récursif casse très vite les performances sur de l'SQL.
D'où la technique que j'ai fournie : pratique, puissante, performante et
dont apparemment tout le monde se fout.


Non pas tout le monde.
Cependant, attention aux raccourcis trompeurs.
Cette technique et puissante, performante ... en lecture.
En effet, l'insertion de données est une catastrophe en terme de
performances et extremenent risquée lorsqu'on ne dispose pas des
transactions.

1 2