2012-05-04 16 views
1

私はデータベース駆動型のナビゲーションを構築しています。私は自分のデータ構造を構築する方法で助けが必要です。私は非常に再帰を経験していませんが、これが最も可能性の高い方法です。データベーステーブルには、idカラム、parent_idカラム、およびlabelカラムがあります。このメソッドを呼び出した結果、私にデータ構造が提供されます。私のデータ構造が次のようになる方法:PHPネストされたナビゲーション

  • parent_idが0のレコードはルート要素とみなされます。
  • 各ルート要素は、ルート要素idと等しいparent_idを含む要素の配列を保持する子が存在する場合、子の配列を含みます。
  • 子供には直接の子に等しいparent_idsを含む子配列が含まれている可能性があります(これは再帰的な点になります)
  • parent_idが0ではないレコードが存在する場合、子の配列に追加されます要素。ここで

は、データ構造がどのように見えるかです:

$data = array(
    'home' => array( 
     'id' => 1, 
     'parent_id' => 0, 
     'label' => 'Test', 
     'children' => array(
      'immediatechild' => array(
       'id' => 2, 
       'parent_id' => 1, 
       'label' => 'Test1', 
       'children' => array(
       'grandchild' => array(
        'id' => 3, 
        'parent_id' => 2, 
        'label' => 'Test12', 
      )) 
     )) 
) 

)。

ここで私はちょっと思いついたことがあります。それは正しいものではありませんが、私が使用したいものと、それを修正するのに役立ついくつかのIDがあります。

<?php 
// should i pass records and parent_id? anything else? 
function buildNav($data,$parent_id=0) 
{ 
    $finalData = array(); 
    // if is array than loop 
    if(is_array($data)){ 
     foreach($data as $record){ 
      // not sure how/what to check here 
     if(isset($record['parent_id']) && ($record['parent_id'] !== $parent_id){ 
      // what should i pass into the recursive call?    
      $finalData['children'][$record['label'][] = buildNav($record,$record['parent_id']); 
     } 
     } 
    } else { 
     $finalData[] = array(
     'id' => $data['id'], 
     'parent_id' => $parent_id, 
     'label' => $data['label'],   
    ) 
    } 
    return $finalData 
} 

ありがとうございました!

+0

あなたの質問は何ですか? – hakre

+0

MySQLをデータストアとして使用している場合は、次のようなものがあります。DBの側には、 – Treffynnon

+0

FIxedのhttp://mikehillyer.com/articles/managing-hierarchical-data-in-mysql/があります。私は、ナビゲーションデータ構造を構築するPHPコードを探しています – jkushner

答えて

2

最も簡単なソリューションです(あなたは階層を示すために、FKとして親IDを使用して、リレーショナルrepresenationに格納されたデータを持っていると仮定した場合)にだけ力ずくそれ:

$start=array(
    array('parent_id'=>0, 'title'=>'Some root level node', 'id'=>100), 
    array('parent_id'=>0, 'title'=>'Other root level node', 'id'=>193), 
    array('parent_id'=>100, 'title'=>'a child node', 'id'=>83), 
    .... 
); 
// NB this method will work better if you sort the list by parent id 

$tree=get_children($start, 0); 

function get_children(&$arr, $parent) 
{ 
    static $out_index; 
    $i=0; 
    $out=array(); 
    foreach($arr as $k=>$node) { 
     if ($node['parent_id']==$parent) { 
     ++$i; 
     $out[$out_index+$i]=$node; 
     if (count($arr)>1) { 
      $out[$out_index+$i]['children']=get_children($arr, $node['id']); 
     } 
     unset($arr[$k]); 
    } 
    $out_index+=$i; 
    if ($i) { 
     return $out; 
    } else { 
     return false; 
    } 
} 

しかし、よりよい解決策にありますデータベースのデータにはadjacency list modelを使用します。暫定的な解決策として、ツリー配列をシリアル化し、毎回解析するのではなくファイルにキャッシュしたいと思うかもしれません。

+0

私の方法を使用するのが好きです。私はその実力があるかどうかを知っていますか?おそらく修正する必要があります。 – jkushner