fonction recursive

WRInaute occasionnel
salut,

ca ne doit pas etre mon jour, un truc qui me semblait évident ne marche pas

l'idee est de chercher dans ma table toutes les lignes qui ont le meme parent, en verifiant le parent de chaque ligne de manière recursive


Code:
function recup_art5($idarticle){
	$x = mysql_query("SELECT * FROM article WHERE parent='$idarticle'");
	if(mysql_num_rows($x)){
		for ($i=0 ; $i<mysql_num_rows($x) ; $i++){
		$id = mysql_result($x,$i,"id");
		$body = mysql_result($x,$i,"body");
			if($body>0){return "toto"; }
			recup_art5($id);
		}
	}
}

la fonction ne me retourne rien meme si body>0

Une idée ?

Merci
 
WRInaute accro
Met des echo de tes variable tu verra ou ça coince ...
Sinon c'est quoi la structure de ta table car de la récursivité pour ça me semble bizarre .
 
WRInaute occasionnel
En fait je n'ai pas compris comment fonctionnait la fct return

Code:
function rr($id){
	if($id>10){echo "toto"; return "toto";}
	$id++;
	echo $id;
	rr($id);
}
echo rr(5);

le echo "toto" fonctionne dans la fonction, mais le echo rr(5) ne me renvoi pas "toto"

Comment je dois faire pour que ma fonction me retourne "toto" ?

Merci
 
WRInaute occasionnel
j'ai l'ai fait fonctionner en passant par une variable globale...

Code:
function rr($id){
   global $var;
   if($id>10){$var ="toto"; return 1;}
   $id++;
   rr($id);
}

rr(5);
echo $var;
 
WRInaute accro
chava2b a dit:
En fait je n'ai pas compris comment fonctionnait la fct return
le echo "toto" fonctionne dans la fonction, mais le echo rr(5) ne me renvoi pas "toto"
Comment je dois faire pour que ma fonction me retourne "toto" ?
tu devrais revoir les bases de la récursivité car tu patauge là. Return est une rupture de séquence qui retourne une donnée, "return $x" va suspendre le cours du programme et renvoyer à la ligne appelante la valeur de x.

si tu écris :
$maValeur = maFonction() en ligne 10 tu provoque un appel à la fonction "maFonction".
si dans cette fonction la ligne return "toto" est rencontrée tu passera a la ligne 11 de ton code avec la valeur "toto" dans la variable "maValeur".

modifie ton code comme ceci et teste le :
PHP:
<span class="syntaxdefault">function rr</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">$id</span><span class="syntaxkeyword">){<br /></span><span class="syntaxdefault">   if</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">$id</span><span class="syntaxkeyword">></span><span class="syntaxdefault">10</span><span class="syntaxkeyword">){</span><span class="syntaxdefault">return </span><span class="syntaxstring">"toto"</span><span class="syntaxkeyword">;}<br /></span><span class="syntaxdefault">   $id</span><span class="syntaxkeyword">++;<br /></span><span class="syntaxdefault">   echo $id</span><span class="syntaxkeyword">;<br /></span><span class="syntaxdefault">   return rr</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">$id</span><span class="syntaxkeyword">);<br />}<br /></span><span class="syntaxdefault">echo rr</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">8</span><span class="syntaxkeyword">);</span><span class="syntaxdefault"></span>
Le truc de la récursivité c'est bien sur que la fonction s'auto appelle sous condition mais qu'elle renvoie un truc dans tous les cas donc y compris quand elle s'auto appelle.
là tel que elle va te renvoyer : 91011toto
91011 correspondant aux echo des 3 itérations (echo $id;) avant que id soit supérieur a 10 et toto une fois le test passé avec une sortie "fixe" formalisé par l'echo de l'appel initial (echo rr(8)).
C'est "récursif" mais inutile ...
Tu aurais aussi vite fait de l'écrire ainsi même si c'est pas récursif :
PHP:
<span class="syntaxdefault">function bb</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">$id</span><span class="syntaxkeyword">){<br /></span><span class="syntaxdefault">  while</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">$id</span><span class="syntaxkeyword"><=</span><span class="syntaxdefault">10</span><span class="syntaxkeyword">){<br /></span><span class="syntaxdefault">    $id</span><span class="syntaxkeyword">++;<br /></span><span class="syntaxdefault">    echo $id</span><span class="syntaxkeyword">;<br /></span><span class="syntaxdefault">  </span><span class="syntaxkeyword">}<br /></span><span class="syntaxdefault">  return </span><span class="syntaxstring">"toto"</span><span class="syntaxkeyword">;<br />}<br /></span><span class="syntaxdefault">echo bb</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">8</span><span class="syntaxkeyword">);&nbsp;</span><span class="syntaxdefault"></span>
on pourrait aussi l'écrire encore plus simplement avec une boucle ...
La vrai question c'est pourquoi de la récursivité car ça dépende de ta table ... Une requête simple remplace souvent un traitement lourd hors "chercher dans ma table toutes les lignes qui ont le même parent" c'est tout sauf un besoin récursif.
Tu voudrais "chercher dans ma table toute l'arborescence des je sais pas quoi pour une entrée donnée" là ça se discute.

D'où la question :

zeb a dit:
Sinon c'est quoi la structure de ta table car de la récursivité pour ça me semble bizarre .
 
WRInaute occasionnel
Effectivement le return renvoi l'info a la boucle qui l'a appelé (c'est là où je me plantais)
La fonction rr est EVIDEMENT un test, lol ! pas besoin de faire une recursive pour ca!

Je reprend ma fonction de depart, une table ou sont stockés mes articles ainsi que les répertoires où sont ses articles
Il peut y avoir des répertoires dans des repertoires, d'où la reucrsivité pour recuperer les infos

ma table article (id, parent, body, txt)
body est un booleen qui me dit si c'est un article ou un repertoire
parent prend l'id du repertoire où il est

donc

Code:
1   0   0   REP 1
2   1   0   REP 11
3   1   0   REP 12
4   3   0   REP 121
5   4   1   Mon article qui est dans rep1 / rep12 / rep 121

Ma fonction doit tester s'il y a un article dans le rep ou dans les sous-rep

j'ai réussi à la faire fonctionner en passant une variable en global, je lance ma fonction puis je teste ma variable

Code:
function recup_art5($idarticle){
   $global $plein;
   $x = mysql_query("SELECT * FROM article WHERE parent='$idarticle'");
   if(mysql_num_rows($x)){
      for ($i=0 ; $i<mysql_num_rows($x) ; $i++){
      $id = mysql_result($x,$i,"id");
      $body = mysql_result($x,$i,"body");
         if($body>0){$plein = 1; return 1; }
         recup_art5($id);
      }
   }
}
 
WRInaute passionné
2 conseils:

- la recursivité en php est limité en nombre (renseigne toi)
- tes noms de functions sont vraiment horribles, renseigne toi sur le nommage des functions, car quand tu auras laisser ton code fonctionner bien tranquillement et qu'un beau matin tu veuille reprendre ton code, alors toi même n'y comprendra plus rien du tout...Je t'entend dire "ouais...bof...il fait suer celui là..." mais crois moi sur parole, tu va droit dans le mur avec ce genre de pratique (c'est bon? je t'ai fais assez flipper?).
 
WRInaute occasionnel
1. Pas de probleme de limites, je peux configurer mon serveur comme je veux/

2. effectivement je nomme un peu mieux mon code, là je suis parti d'une fonction qui existait pour la modifier et faire mes tests. Sinon apres il y a des avantage à ne pas trop en faire; dans 3 ans quand je reviens dessus, je suis obligé de re-reflechir, ca me permet de mieux comprendre ma fonction et voir de la debugger/optimiser/modifer ...
 
WRInaute accro
spout a dit:
Pour le futur regarde la technique MPTT: http://www.sitepoint.com/hierarchical-data-database-2/
En 1 seule query tu peux lire tout l'arbre ou un enfant et tous ses parents.

C'est de cette façon que sont organisés les menus Joomla!, et c'est pour cette raison que j'adore bosser avec ce CMS :)

spout a dit:
Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live.

http://lesjoiesducode.fr/post/45188616951/quand-je-forme-le-stagiaire
 
Discussions similaires
Haut