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

0/5 (12 avis)

Vue 8 087 fois - Téléchargée 224 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
Teclis01 Messages postés 1423 Date d'inscription mardi 14 décembre 2004 Statut Membre Dernière intervention 29 décembre 2012 4
14 janv. 2009 à 09:35
_un foreach sans if(!empty($aArray)) pas très élégant...
_un global ... encore moins élégant...
_Pas d'exemple d'utilisation
_$parent=="" or $parent==0 très moche ^_^ Soit il a un id>0 auquel cas il a un parent soit non pq testes tu la chaine vide?

A vos claviers!
cs_foxmaster Messages postés 38 Date d'inscription mercredi 9 février 2005 Statut Membre Dernière intervention 23 septembre 2013
14 janv. 2009 à 14:00
Merci pour ces commentaires j'ai appliqué certaines des modifs données
(if(!empty) et les parent inutiles,
concernant le global, je ne vois pas d'autre solution pour récupérer de nouveau sous forme de tableau filtrés les données.

concernant l'exemple
il y en a un ici
http://foxmaster.info/recursivite/recursivite.php
comme précisé dans la partie supérieure
codefalse Messages postés 1123 Date d'inscription mardi 8 janvier 2002 Statut Modérateur Dernière intervention 21 avril 2009 1
14 janv. 2009 à 14:29
et à ta place je testerai aussi si le tableau donné respecte bien la demande (si les diverses clées (id, nom, niveau, dependance) sont présentent avec un petit isset :)
Teclis01 Messages postés 1423 Date d'inscription mardi 14 décembre 2004 Statut Membre Dernière intervention 29 décembre 2012 4
14 janv. 2009 à 15:06
pour ton global, suffit de lui passer en param d'entrée à ta fonction récursive.
function recurs($tb,$parent,$appelid,$newtab=array())
et tu le retournes.
ensuite tu changes pas sont type en cours de route (Ligne 1 c'est un string vide puis devient un array)
cs_foxmaster Messages postés 38 Date d'inscription mercredi 9 février 2005 Statut Membre Dernière intervention 23 septembre 2013
14 janv. 2009 à 18:35
j'ai de nouveau apporté les modifs de codefalse et teclis01
si vous soyez autre chose...?
j'ai intégré un exemple.

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.