fonction récursive

chris801
Invité n'ayant pas de compte PHPfrance

16 oct. 2010, 09:07

bonjour

je galère depuis quelques heures déjà sur mon petit problème. Les fonction récursives, je ne domine pas.

voila, je doit simplement lister des catégories.
exemple :
j'ai les catégories suivantes

Cat principale 1
-- Ss catégorie 1
-- Ss catégorie 2
-- Ss catégorie 3
-- -- Ss Ss catégorie 1

Cat principale 2
-- Ss catégorie 1
-- Ss catégorie 2
-- -- <souligne>Ss Ss catégorie 1 </souligne>
-- Ss catégorie 3

je suis dans la sous sous catégorie 1 de la cat princiale 2 (en souligné ici) et je veux afficher :
Cat principale 2 > Ss catégorie 2 > Ss Ss catégorie 1.


j'ai donc créé cette fonction pour y parvenir
function arrayNavigueBoutique($parent,$niveau,$array) {
	
	//==> boucle d'affichage des cat
	foreach ($array AS $noeud) 
	{

		if ($parent == $noeud['cat_id']) 
		{ 
		$parent = $noeud['cat_id_parent'];
		$array2['cat_id'][] = $noeud['cat_id'];
		$array2['cat_nom'][] = $noeud['cat_nom'];
		$array2['cat_id_parent'][] = $noeud['cat_id_parent'];

		// récusrsivité pour sous catégories
		arrayNavigueBoutique($parent,($niveau + 1),$array);
		}
	}

return $array2;
}
$parent = l'id de la catégorie active
$niveau, = je ne m'en sert pas pour le moment, mais il représente le niveau de catégorie ici c'est le départ donc 0
$array = un tableau associatif de toutes mes catégories

Mais je ne parvient pas à obtenir le résultat escompté
Donc voila, si quelqu'un pouvait m'aider solutionner ce problème

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 10684 Messages

16 oct. 2010, 09:17

Dans ta fonction, lorsque tu fais appel à arrayNavigueBoutique(), tu ne récupères pas le résultat retourné ($array2). Du coup ton tableau n'est pas complété au fur et à mesure de tes appel récursifs :)
Ce n'est pas en améliorant la bougie que l'on a inventé l'ampoule...

chris801
Invité n'ayant pas de compte PHPfrance

16 oct. 2010, 09:39

il faut donc que je transfert également array2 en plus de array,
j'initialise donc mon array2 avant de le transmettre pour la première boucle.
je vais essayer ça, merci

chris801
Invité n'ayant pas de compte PHPfrance

16 oct. 2010, 09:52

bon j'ai fait la modif et ça ne fonctionne toujour pas
function arrayNavigueBoutique($parent,$niveau,$array,$array2) {

	//==> boucle d'affichage des cat
	foreach ($array AS $noeud) 
	{
		if ($parent == $noeud['cat_id']) 
		{ 
		$parent = $noeud['cat_id_parent'];
		$array2['cat_id'][] = $noeud['cat_id'];
		$array2['cat_nom'][] = $noeud['cat_nom'];
		$array2['cat_id_parent'][] = $noeud['cat_id_parent'];

		// récusrsivité pour sous catégories
		arrayNavigueBoutique($parent,($niveau + 1),$array,$array2);
		}
	}

return $array2;
}

chris801
Invité n'ayant pas de compte PHPfrance

16 oct. 2010, 10:09

les catégories sont insérées dans l'array2, mais la boucle fait deux tours de trop

les premières boucles donnent ceci

["cat_nom"]=>
array(5) {
[0]=>
string(5) "test6"
[1]=>
string(6) "cat 4 "
[2]=>
string(4) "cat3"
[3]=>
string(37) "cordes poignées lestées"
[4]=>
string(22) "Cordes à sauter"
}

et l'avant dernier tour

["cat_nom"]=>
array(4) {
[0]=>
string(5) "test6"
[1]=>
string(6) "cat 4 "
[2]=>
string(4) "cat3"
[3]=>
string(37) "cordes poignées lestées"
}

le dernier tour

["cat_nom"]=>
array(1) {
[0]=>
string(5) "test6"
}

chris801
Invité n'ayant pas de compte PHPfrance

16 oct. 2010, 10:12

petite précision

mon tableau des catégories ressemble à ça
cat_id (index de l'entré)
cat_nom (nom de la catégorie)
cat_publication (publication)
cat_id_parent (catégorie parent)
cat_description (description de la catégorie)

si il s'agit d'une catégorie principale, la cat_id_parent est égale à 0

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 10684 Messages

16 oct. 2010, 10:19

Pas transféré, mais récupéré :)

En fait tu as deux solutions, soit tu récupères le résultat de ta fonction dans ta fonction, soit tu stock le résultat directement dans un tableau global externe à ta fonction.

Un exemple basique :
function addOne($val) {
  if ($val < 10) 
    $val = addOne($val + 1); // c'est ici que je récupère la valeur retourné récursivement.
 
  return $val;
} 
echo addOne(5);
Si je fais juste appel à addOne() sans stocker le résultat dans $val, la valeur de $val n'est modifiée que localement et est perdue à chaque fois que je remonte à l'itération précédente. (dans ton cas, il ne faut pas juste écraser, mais compléter le tableau array2 propre à chaque itération au fur et à mesure, pour au final pouvoir retourner un tableau complet :))

L'autre solution consiste à déclarer une variable globale externe à la fonction, que chaque itération mettra à jour :
$valExterne = 0;
function addOne($val) {
  global $valExterne; // je déclare la référence à ma variable externe
  if ($val < 10) {
    $valExterne = $val; // chaque itération met à jour la variable externe 
    addOne($val + 1);
  } 
} 
addOne(5);
echo $valExterne;
Ce n'est pas en améliorant la bougie que l'on a inventé l'ampoule...

chris801
Invité n'ayant pas de compte PHPfrance

16 oct. 2010, 12:18

Merci pour ce code,

finalement je ne vais pas transférer ma variable avec return, j'affiche le résultat directement dans la fonction, même si j'aurais préféré l'autre solution.
function arrayNavigueBoutique($parent,$niveau,$array,$array2) {

	//==> boucle d'affichage des cat
	foreach ($array AS $noeud) 
	{

		if ($parent == $noeud['cat_id'] AND $parent != 0 AND $niveau == 0) 
		{ 
		$parent = $noeud['cat_id_parent'];
		$array2['cat_id'][] = $noeud['cat_id'];
		$array2['cat_nom'][] = $noeud['cat_nom'];
		$array2['cat_id_parent'][] = $noeud['cat_id_parent'];
		
			if ($noeud['cat_id_parent'] != 0 ) {
			
				// récusrsivité pour sous catégories
				arrayNavigueBoutique($parent,($niveau++),$array,$array2);

			}
		}
	}

	if ($niveau == 0) {
		$nb_produit = count($array2['cat_id']);
		echo '<br>';
		for($i = $nb_produit; $i > 0 ; $i--)
		{	
		echo $array2['cat_nom'][$i].' || ';
		}
	}
}