2009-05-07 16 views
1

私は深さの制限がないようにいくつかのナビゲーション関連の機能を持っています。これらは、CSSメニュー、ブレッドクラムトレイルなどを生成します。適切に再帰

明示的なループを行わずに深度またはルートへの各パスをどのように機能させるかについて、私は困惑しています。

次の例は、ページの最上位の親が必要な典型的な例です。最上位のフィールドは、parentフィールドにゼロの値を持ちます。

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 

誰もが道を指し示すのに役立つアドバイスや類似したコードやtuteリンクを持っている:ここでは

は、明示的にループされたバージョンですか?

答えて

8

これは、whileループのように簡単に表現可能です:

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

$nodeは今、一番上の要素が含まれています。

+1

をあなたは$ nodeと$ thisを逆にしました(つまり、$ this-> retrieve( "id = '$ node-> parent'")ですが、そのアイデアは明白です) – Stephan202

+0

@ Stephan202:ありがとうございます私は答えを修正しました – Welbog

+0

は最初に$ node = $ thisではありませんか? – Petrunov

0

私はそれをテストしていませんが、それは動作するはず..:

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

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

} 
+0

ありがとうPetrunov! – jerrygarciuh

1

Welbog'sanswerは素敵ですが、完全を期すために、私は別の再帰的なソリューションに追加されます:私は思う

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

    return foo($this); 
} 
関連する問題