2009-05-07 5 views
1

J'ai plusieurs fonctions liées à la navigation que je voudrais ne pas avoir de limites de profondeur. Ceux-ci génèrent des menus CSS, des pistes de navigation et similaires.Récursif correctement

Je suis perplexe quant à la façon dont je ferais que les fonctions suivent chaque chemin vers la profondeur ou vers la racine sans boucle explicite.

Voici un exemple typique où je veux le parent le plus élevé d'une page. Le plus haut aura une valeur de zéro dans son champ parent.

Voici la version en boucle explicitement:

function topPg() { 
    $p = $this->retrieve("id = '$this->parent'"); 
    if ($p->parent != 0) { 
     $gp = $this->retrieve("id = '$p->parent'"); 
     if ($gp->parent != 0) { 
      $ggp = $this->retrieve("id = '$gp->parent'"); 
      if ($ggp->parent != 0) { 
       $gggp = $this->retrieve("id = '$ggp->parent'"); 
       // ad naseum 
      } else { 
       return $ggp; 
      } 
     } else { 
      return $gp; 
     } 
    } else { 
     return $p; 
    } 
} // func 

Quelqu'un a des conseils ou un code similaire ou un lien Tute pour aider à montrer la voie?

Répondre

8

Il est facilement exprimable comme une boucle while:

$node = $this; 
while ($node->parent != 0) { 
    $node = $this->retrieve("id = '$node->parent'"); 
} 

$node contient maintenant l'élément supérieur.

+1

Je pense vous avez inversé $ node et $ this (c'est-à-dire, cela devrait être $ this-> retrieve ("id = '$ node-> parent'"), mais l'idée est claire – Stephan202

+0

@ Stephan202: Vous avez raison. le commentaire J'ai corrigé la réponse – Welbog

+0

n'est pas $ node = $ this en premier lieu? – Petrunov

0

Je ne l'ai pas testé, mais il devrait fonctionner ..:

function recurse($pg) 
{ 
    $parent_pg = $pg->retrieve('id = ' . $this->parent); 

    if($parent_pg->parent != 0) 
    { 
     recurse($parent_pg); 
    } 
    else 
    { 
     return $pg; 
    } 

} 
+0

Merci Petrunov! – jerrygarciuh

1

Welbog'sanswer est la plus belle, mais pour être complet, je vais ajouter une autre solution récursive:

function topPg() { 
    function foo($p) { 
    $gp = $this->retrieve("id = '$p->parent'"); 
    return ($gp->parent == 0) ? $p : foo($gp); 
    } 

    return foo($this); 
} 
Questions connexes