2012-05-04 107 views
1

我正在构建一个数据库驱动的导航,我需要一些帮助来构建我的数据结构。我对递归不是很有经验,但是这很可能是这样做的路径。数据库表有一个id列,一个parent_id列和一个标签列。调用方法的结果为我提供了数据结构。我的数据结构应导致以下方式:PHP嵌套导航

  • parent_id为0的记录被假定为根元素。
  • 如果存在子元素,则每个根元素都包含一个子元素数组,该元素包含parent_id等于根元素id的元素数组。
  • 子元素可能包含一个包含parent_id等于直接子元素的子元素数组(这将是递归点)
  • 当存在包含不为0的parent_id的记录时,它将被添加到子元素的数组中元素。

下面是数据结构应该是什么样子:

$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作为数据存储,那么您可能会喜欢这样的:http://mikehillyer.com/articles/managing-hierarchical-data-in-mysql/对于事物 – Treffynnon

+0

的数据库端FIxed。我正在寻找PHP代码来建立导航数据结构 – jkushner

回答

2

简单的解决方案(假设你有使用父ID为FK指示层次存储在关系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