Classe qui permet de generer un arbre

Soyez le premier à donner votre avis sur cette source.

Vue 8 039 fois - Téléchargée 526 fois

Description

Voici une classe qui permet de générer un arbre sous forme d'un tableau multidimensionnel.
L'avantage de cette classe c'est qu'elle ne lit qu'une fois la requete en créant une liste des éléments parents et enfants sous forme d'un tableau. Et à partir de ce tableau, on peut faire tout ce qu'on veut.

Source / Exemple :


<?php
/*

  • fichier: tree.class.php
  • description: classe pour traiter l'arborescence des éléments
  • auteur: gagah
  • /
class Tree { // tableau multidimension qui recoit l'arborescence private $node = array(); // nom du premier élément. pour id=0 private $root; /**************************************************************
  • constructeur:
*
                                                                                                                            • /
public function __construct($root='Base') { $this->root = $root; $this->clear(); } /****************************************************************
  • make: création d'un tableau multidimensionnel pour stocker l'arborescence
  • @param $idparent (int): identifiant parent
  • @param $id (int): identifiant
  • @param $name(string): nom de l'élément
*
                                                                                                                                • /
public function make($idparent, $id, $name) { $this->makeArrayNode($idparent, $id, $name, $this->node); } /**************************************************************
  • child: retourne un tableau en 2 dimensions (id et name) de tous les
  • arborescents enfants d'un ID.
  • @param $id (int): identifiant de l'élément à lister
  • @param $all (booleen): true si tous les sous-éléments inclus
  • @param $included (booleen): true si on doit inclure aussi l'identifiant
*
                                                                                                                            • /
public function child($id, $all=false, $included=false) { $temp = array(); $this->childNode($this->node, $temp, $id, $all, $included); return $temp; } /**************************************************************
  • listUL: retourne un tableau en 2 dimensions (id et name) de tous les
  • arborescents enfants d'un ID.
  • @param $id (int): identifiant de l'élément à lister
  • @param $all (booleen): true si tous les sous-éléments inclus
  • @param $included (booleen): true si on doit inclure aussi l'identifiant
*
                                                                                                                            • /
public function listUL($id, $all=false, $included=false) { $str = $this->listNode($this->node, $id, $all, $included); if(!empty($str)) $str = "<ul>\r\n". $str ."</ul>\r\n"; return $str; } /**************************************************************
  • clear: efface tous les éléments dans le noeud
*
                                                                                                                            • /
public function clear() { $this->node = array(); $this->node['id'] = 0; $this->node['name'] = $this->root; $this->node['child'] = array(); } /**************************************************************
  • getArray: retourne un tableau miltidimensionnel avec comme clés : id,
  • name et child
*
                                                                                                                            • /
public function getArray() { return $this->node; } /**************************************************************
  • makeArrayNode:
*
                                                                                                                            • /
private function makeArrayNode($idparent, $id, $name, &$tab) { if(!isset($tab['id']) || !isset($tab['child'])) return false; if($tab['id'] == $idparent) { $temp = array(); $temp['id'] = $id; $temp['name'] = $name; $temp['child'] = array(); array_push($tab['child'], $temp); return true; } else { $count = count($tab['child']); for($i=0; $i<$count; $i++) { if($this->makeArrayNode($idparent, $id, $name, $tab['child'][$i])) return true; } return false; } } /**************************************************************
  • listNode: retourne une chaine de la liste
*
                                                                                                                            • /
private function listNode($tab, $id, $all=false, $included=false, $find=false) { if($find && $all) $str = '<li>'. $tab['name'] .'</li>'; else if(!$find && ($tab['id'] == $id)) { if($included) $str = '<li>'. $tab['name'] .'</li>'; else $str = ''; $find = true; } else $str = ''; if(!$find || ($find && $all)) { if($find) $str .= '<ul>'; foreach($tab['child'] as $value) $str .= $this->listNode($value, $id, $all, $included, $find); if($find) $str .= '</ul>'; } else { $str .= '<ul>'; foreach($tab['child'] as $value) $str .= '<li>'. $value['name'] .'</li>'; $str .= '</ul>'; } return $str; } /**************************************************************
  • childNode: retourne un tableau pour la liste des nodes enfants
*
                                                                                                                            • /
private function childNode($tab, &$ret, $id, $all=false, $included=false, $find=false) { if($find && $all) $ret[] = array('id'=>$tab['id'], 'name'=>$tab['name']); else if(!$find && ($tab['id'] == $id)) { if($included) $ret[] = array('id'=>$tab['id'], 'name'=>$tab['name']); $find = true; } if(!$find || ($find && $all)) { foreach($tab['child'] as $value) $this->childNode($value, $ret, $id, $all, $included, $find); } else { foreach($tab['child'] as $value) $ret[] = array('id'=>$value['id'], 'name'=>$value['name']); } } }

Codes Sources

A voir également

Ajouter un commentaire

Commentaires

Messages postés
395
Date d'inscription
jeudi 26 août 2004
Statut
Membre
Dernière intervention
19 juin 2009
1
Source amusante,
il est vrai qu'on apprend rapidement à utiliser une structure récursive pour gérer les arbres, simplement chainé ou doublement chainé.

Rapidement une classe node va avoir un (simplement) ou deux (doublement) pointeur sur d'autre classe node. Pour les simples, c'est généralement le suivant, pour les doubles on ajoute le précédent, ensuite on peu circuler dans la node sans problème. Il ne reste plus qu'a mettre les methodes del(), add(), move() ... et tout ce qui te paraitera utile.

Dans un chaine, il n'y a que deux elements maximum autour d'une node (le précedent et le suivant), le problème de l'arbre est qu'une node a comme dénominateur un parent qui peut être le méme que pour d'autre node. La solution reviens alors à soit faire un arbre simple (on indique que le parent) soit un arbre complexe, chaque node aura en reférence son parent mais aussi le nombre d'enfant qu'elle possède et au besoin un indexage.
Pour finir il faut, là aussi, ajouter les méthodes, un peu plus complexe:
-add_child() / ajouter un enfant
-add_same() / ajouter une node au même niveau
-del() / ne pas oublier que supprimer un parent doit aussi tuer tout ces enfants ! (je sais c'est mal mais c'est du code)
-move_up() / permet de remonter l'enfant au niveau de son parent
et toutes les méthodes qui peuvent être utile ...

Désolé pour mon français, j'ai beau me relire ça persiste!

Ergo.
Messages postés
2483
Date d'inscription
jeudi 30 novembre 2006
Statut
Membre
Dernière intervention
14 janvier 2011
15
Désolé... ^^ Mais j'adooooore les itérateurs...

Euh donc, logiquement, avec des itérateurs, ton code sera infiniment plus lisible, infiniment plus facile à maintenir, etc. Par contre, utiliser des itérateurs risque de faire passer le niveau de débutant à initié, et le code, s'il est plus lisible, ne sera pas forcément plus facile d'accès pour un débutant (précision : pour un débutant qui ne veut pas chercher à comprendre).
La classe RecursiveArrayIterator de la SPL est toute désignée pour manipuler des tableaux "récursifs".
http://www.php.net/~helly/php/ext/spl/
Messages postés
509
Date d'inscription
samedi 28 juin 2003
Statut
Membre
Dernière intervention
3 août 2010

Je le savais, je me dis si je poste cette source on me demandera d'utiliser des itérateurs, des interfaces...
Je sais pas si avec un tableau le code est plus leger ou avec des itérateurs?
Messages postés
2483
Date d'inscription
jeudi 30 novembre 2006
Statut
Membre
Dernière intervention
14 janvier 2011
15
Salut,

Puisque ta source est manifestement du PHP5, pourquoi ne pas utiliser des itérateurs ?
Messages postés
509
Date d'inscription
samedi 28 juin 2003
Statut
Membre
Dernière intervention
3 août 2010

Je commence à comprendre ce que tu voulais me dire.
Afficher les 13 commentaires

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.