Hiérarchisation d'un tableau par fonction récursive

Soyez le premier à donner votre avis sur cette source.

Vue 6 874 fois - Téléchargée 191 fois

Description

Cette fonction permet a partir d'un tableau (array) soit généré a la main soit comme dans l'exemple généré a partir d'une base de donnée
de trier les élément de maniere hiérarchique
parent
enfant
enfant de l'enfant
etc....
la base de donnée est faite de la façon suivante:

id int(11) <== auto_increment (identifiant unique)
nom text <== nom de l'élement
niveau int(11) <== quelle position il a (pas obligatoire)
dependance int(11) <== id de l'objet parent (0 si il n'en a pas)

vous pouvez tester ici
http://foxmaster.info/recursivite/recursivite.php

et télécharger la source + BDD ici
http://foxmaster.info/telechargements/recursivite.zip

Source / Exemple :


<?php
//fonction récursive
//$td => tableau à traiter, 
//$parent => va etre apelé pour chercher les element dépendant de l'élément précédemment traité
//$appelid => variable qui si définie définira l'id comme racine et cherchera les élement enfants a partir de ce point
function recurs($tb,$parent,$appelid,$newtab= array())
{
	if(!empty($tb))
	{//Pour chaque élément du tableau...
		foreach($tb as $key => $value)
		{
			if (isset ($value['id'], $value['nom'], $value['niveau'], $value['dependance'])) 
			{
				if(!$appelid) //si on ne par pas d'un autre point
				{
					//si il n'y a pas de dépendance (racine) 
					if($value['dependance']==0 and $parent==0)
					{
						$newtab[] = array('id' => $value['id'],'nom' => $value['nom'], 'niveau' => $value['niveau'], 'dependance' => $value['dependance']);
						$newtab = recurs($tb,$value['id'],0,$newtab);
					}
					//si la fonction déja bouclé une premiere fois on cherche les objets enfant au parent appelé
					if($parent!=0 and $value['dependance']==$parent)
					{
						$newtab[] = array('id' => $value['id'],'nom' => $value['nom'], 'niveau' => $value['niveau'], 'dependance' => $value['dependance']);
						$newtab = recurs($tb,$value['id'],0,$newtab);// et on rappelle la fonction
					}
				}
				else
				{ // si la variable $appelid a été appelée
					if($value['id']==$appelid) //on cherche l'élement correspondant qui fera office de racine
					{
						$newtab[]= array('id' => $value['id'],'nom' => $value['nom'], 'niveau' => $value['niveau'], 'dependance' => $value['dependance']);
						$newtab = recurs($tb,$value['id'],0,$newtab); // et on rapelle la fonction 
					}
				}
			}
		}
	}
	return $newtab;
}
//création du tableau
$tb[] = array('id' => 1,'nom' => 'Fruits', 'niveau' => 1, 'dependance' => 0);
$tb[] = array('id' => 2,'nom' => 'Légumes', 'niveau' => 1, 'dependance' => 0);
$tb[] = array('id' => 3,'nom' => 'Viandes', 'niveau' => 1, 'dependance' => 0);
$tb[] = array('id' => 4,'nom' => 'Poissons', 'niveau' => 1, 'dependance' => 0);
$tb[] = array('id' => 5,'nom' => 'Agrumes', 'niveau' => 2, 'dependance' => 1);
$tb[] = array('id' => 6,'nom' => 'Racines', 'niveau' => 2, 'dependance' => 2);
$tb[] = array('id' => 7,'nom' => 'Viandes Blanches', 'niveau' => 2, 'dependance' => 3);
$tb[] = array('id' => 8,'nom' => 'Viandes Rouges', 'niveau' => 2, 'dependance' => 3);
$tb[] = array('id' => 9,'nom' => 'Exotiques', 'niveau' => 2, 'dependance' => 1);
$tb[] = array('id' => 10,'nom' => 'De mer', 'niveau' => 2, 'dependance' => 4);
$tb[] = array('id' => 11,'nom' => 'Oranges', 'niveau' => 3, 'dependance' => 5);
$tb[] = array('id' => 12,'nom' => 'Carottes', 'niveau' => 3, 'dependance' => 6);
$tb[] = array('id' => 13,'nom' => 'Veau', 'niveau' => 3, 'dependance' => 7);
$tb[] = array('id' => 14,'nom' => 'Cheval', 'niveau' => 3, 'dependance' => 8);
$tb[] = array('id' => 15,'nom' => 'Grisés', 'niveau' => 3, 'dependance' => 10);
$tb[] = array('id' => 16,'nom' => 'Fruits de la passion', 'niveau' => 3, 'dependance' => 9);
$tb[] = array('id' => 17,'nom' => 'Pommes de Terres', 'niveau' => 3, 'dependance' => 6);
$tb[] = array('id' => 18,'nom' => 'jaunes', 'niveau' => 4, 'dependance' => 17);
$tb[] = array('id' => 19,'nom' => 'rouges', 'niveau' => 4, 'dependance' => 17);
/********************************************/
$newtab = recurs($tb,0,0,''); // on appelle notre fonction de récursivité
echo '
<select name="choix_elements" onchange="window.location.href=\'?choix_elements=\'+this.value;">
	<option value="0">Sélectionner</option>\n';
	foreach($newtab as $key => $valnewtab) // on lis le nouveau tableau généré apres traitement de la fonction
	{
		$nom=$valnewtab['nom'];
		if($key==0){$lvl0=$valnewtab['niveau'];}
		if($valnewtab['niveau']>$lvl0 and $key!=0) 
		{
			for($nv=0;$nv<($valnewtab['niveau']-$lvl0);$nv++)//permet d'ajouter des espaces
			{
				$nom= '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'.$nom;
			}
		}
		echo '	<option value="'.$valnewtab['id'].'" ';
		if($_GET['choix_elements']==$valnewtab['id']){echo 'selected';} //si get appelé et correspond a l'élément traité on di qu'il est sélectionné
		echo'>'.$nom.'</option>\n';
	}
echo '</select>
';
if(isset($_GET['choix_elements']))
{$newtab = recurs($tb,0,$_GET['choix_elements'],'');}
else
{$newtab = recurs($tb,0,0,'');}
echo '<br />
';
foreach($newtab as $key => $valnewtab)
{				
	$nom=$valnewtab['nom'];
	if($key==0){$lvl0=$valnewtab['niveau'];}
	if($valnewtab['niveau']>$lvl0 and $key!=0) 
	{
		
		for($nv=0;$nv<($valnewtab['niveau']-$lvl0);$nv++)//permet d'ajouter des espaces
		{
			$nom= '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'.$nom;
		}
	}
	echo $nom.'<br />';
	//si l'on ne souhaite pas inclure l'élément précédemment sélectionné il suffirait de mettre 
	//if($valnewtab['id']!=$_GET['choix_elements']){echo '$valnewtab[nom] (id : $valnewtab[id])<br />';}
}
?>

Codes Sources

A voir également

Ajouter un commentaire

Commentaires

Messages postés
38
Date d'inscription
mercredi 9 février 2005
Statut
Membre
Dernière intervention
23 septembre 2013

Bonjour,

j'avoue ne pas avoir essayé de pousser la récursivité à un si grand niveau, ta base est-elle bien optimisée?

la requete faisant un appel de toutes les données de la base, peut etre aussi modifier cette requete pour qu'elle ne sélectionne que les champs nécessaires.

bien que mon exemple montre tous les sous éléments , je ne pense pas que l'on ai à montrer tout d'un coup.

je n'ai pas vraiment d'idée et a vrai dire cela fait longtemps que je n'ai pas codé.. mais si tu as une piste, un indice ou des idées, expose les ;)
Messages postés
9
Date d'inscription
vendredi 12 août 2005
Statut
Membre
Dernière intervention
22 juillet 2010

Salut,

J'ai testé ta fonction sur mes catégories. 70 catégories, 3 niveaux de catégories.
Ta fonction est chronophage. J'ai eu un bon Memory Limit.
Il faudrait la revoir un peu :p
Messages postés
30
Date d'inscription
mercredi 2 novembre 2005
Statut
Membre
Dernière intervention
24 février 2010

re salut

et puis juste un détail mais éviter de mettre des echo partout
juste un a la fin sa suffit

$newtab = recurs($tb,0,0,'');
$select.="<select name="choix_elements">\n";
$select.="<option value="0">Sélectionner</option>\n";

foreach($newtab as $key => $valnewtab) {

$nom=$valnewtab['nom'];
if($key==0){$lvl0=$valnewtab['niveau'];}
$style=10*$valnewtab['niveau'];

$select .="<option style="padding-left:".$style."px;" value="".$valnewtab['id'].""";

if($_GET['choix_elements']==$valnewtab['id']){echo "selected";}

$select.=">".$nom."</option>\n";

}
$select.="</select>";

echo $select;
Messages postés
30
Date d'inscription
mercredi 2 novembre 2005
Statut
Membre
Dernière intervention
24 février 2010

salut

moi perso jai pas les

donc jai fait :

$newtab = recurs($tb,0,0,'');
echo "
<select name="choix_elements">
<option value="0">Sélectionner</option>\n";

foreach($newtab as $key => $valnewtab) {

$nom=$valnewtab['nom'];
if($key==0){$lvl0=$valnewtab['niveau'];}
$style=10*$valnewtab['niveau'];

echo "<option style="padding-left:".$style."px;" value="".$valnewtab['id'].""";

if($_GET['choix_elements']==$valnewtab['id']){echo "selected";}

echo">".$nom."</option>\n";

}
echo "</select>";
Messages postés
135
Date d'inscription
samedi 18 janvier 2003
Statut
Membre
Dernière intervention
17 avril 2009

Notice: Undefined index: choix_elements
Afficher les 12 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.