2012-06-08 4 views
1

Задачи:Построить многомерный массив с помощью рекурсивной функции

Я пытаюсь построить рекурсивное дерево, используя функцию и данные из MySQL. Однако результаты не так ожидаемы.

PHP код:

function buildTree($root, $next = array()) 
{ 
    // Sanitize input 
    $root = (int) $root; 

    // Do query 
    $query = "SELECT CID, Item, Parent FROM betyg_category WHERE Status = '1' AND Parent = '{$root}'"; 
    $result = mysql_query($query) or die ('Database Error (' . mysql_errno() . ') ' . mysql_error()); 

    // Loop results 
    while ($row = mysql_fetch_assoc($result)) 
    { 
     $next[$row['CID']] = array (
           'CID' => $row['CID'], 
           'Item' => $row['Item'], 
           'Parent' => $row['Parent'], 
           'Children' => buildTree($row['CID'], $next) 
          ); 
    } 

    // Free mysql result resource 
    mysql_free_result($result); 

    // Return new array 
    return $next; 
} 

$testTree = buildTree(0); 

echo "<xmp>".print_r($testTree, true)."</xmp>"; 

таблица в базе данных выглядит следующим образом:

enter image description here

Я хотел бы массив быть таким:

Array 
(
    [1] => Array 
    (
     [CID] => 1 
     [Item] => Litteratur 
     [Parent] => 0 
     [Children] => Array 
      (
       [2] => Integration av källorna 
       [3] => Belysning av egna resultat 
       [4] => Referenser 
      ) 

    ) 

    and so forth.. 
) 

То есть для каждого родителя => произвести детей, затем перейти к следующему родителю и т. Д. Заранее благодарю за любой совет.

+1

почему вы не предоставите ваши результаты получать, чтобы люди могли видеть то, что Вы в данный момент производите из кода – Lee

+0

@Lee Я хотел бы но результаты просто продолжаются в течение всей вечности, и я должен нажать побег, чтобы браузер не разбился. Другими словами, список слишком длинный, и я чувствовал, что его не следует включать. – kexxcream

+0

change buildTree ($ row ['CID'], $ next) to buildTree ($ row ['CID']) ... что происходит? – Lee

ответ

2

Здесь не требуется рекурсия. Фактически, это будет очень неэффективно, так как вы закончите с проблемой SELECT N + 1. Просто заказать набор результатов родителем:

$query = "SELECT CID, Item, Parent FROM betyg_category WHERE Status = '1' ORDER BY Parent"; 
$result = mysql_query($query); 

$tree = array(); 
while($row = mysql_fetch_assoc($result)) { 
    if($row['Parent'] == 0) { 
     $row['Children'] = array(); 
     $tree[$row['CID']] = $row; 
    } else { 
     $tree[$row['Parent']]['Children'][] = $row; 
    } 
} 

Это будет производить следующее:

Array 
(
    [1] => Array 
     (
      [CID] => 1 
      [Item] => Litteratur 
      [Parent] => 0 
      [Children] => Array 
       (
        [0] => Array 
         (
          [CID] => 2 
          [Item] => Integration av källorna 
          [Parent] => 1 
         ) 

        [1] => Array 
         (
          [CID] => 3 
          [Item] => Belysning 
          [Parent] => 1 
         ) 

        [2] => Array 
         (
          [CID] => 4 
          [Item] => Referenser 
          [Parent] => 1 
         ) 

       ) 

     ) 

    [5] => Array 
     (
      [CID] => 5 
      [Item] => Validitet 
      [Parent] => 0 
      [Children] => Array 
       (
        [0] => Array 
         (
          [CID] => 6 
          [Item] => Huvudsyfte 
          [Parent] => 5 
         ) 

       ) 

     ) 

) 

Если вы хотите, только имя каждого детей, изменение, используйте $tree[$row['Parent']]['Children'][] = $row['Item']; вместо.

+0

Это отлично работает, за исключением того, что мне пришлось изменить его на: $ tree [$ row ['Parent']] ['Children'] [$ row ['CID']] = $ row ['Item']; - но проблема остается. Как отсортировать индекс массива и, что более важно, индекс детей? – kexxcream

+0

@kexxcream Как вы хотите отсортировать его? – alexn

+0

Я хотел его отсортировать по ключевому слову, но @ sephoy08 предоставил ответ на эту проблему. – kexxcream

2

Попробуйте это:

$array = array(); 
while ($row = mysql_fetch_assoc($result)) 
{ 
    if($row['parent'] == '0') 
    { 
     $array[$row['parent']] = ''; 
     $array[$row['parent']]['CID'] = $row['CID']; 
     $array[$row['parent']]['Item'] = $row['item']; 
     $array[$row['parent']]['Parent'] = $row['parent']; 
     $array[$row['parent']]['Children'] = ''; 

    } 
    else 
    { 
     $array[$row['parent']]['Children'][$row['CID']] = $row['item']; 
    } 
} 
echo "<pre>"; 
print_r($array); 

Первый в запросе. Добавить ORDER BY CID ASC затем

$count = array_keys($array); 
foreach($count as $arr) 
{ 
    ksort($array[$arr]['Children']); 
} 
+0

Спасибо, благодаря @alexn-коду, мне тоже удалось найти это решение.Но теперь я просто пропускаю способ сортировки массива $ и Children по их индексу. – kexxcream

+0

ОК я обновил свой ответ – sephoy08

+0

Отлично, это хорошо работает. Я опубликовал окончательное решение ниже. – kexxcream

0

Окончательного решения из всех комментариев:

$query = "SELECT * FROM betyg_category WHERE Status = '1' ORDER BY CID ASC"; 
$result = mysql_query($query) or die ('Database Error (' . mysql_errno() . ') ' . mysql_error()); 

$tree = array(); 

while($row = mysql_fetch_assoc($result)) 
{ 
    if($row['Parent'] == 0) 
    { 
     $row['Children'] = array(); 
     $tree[$row['CID']] = array(
           'CID' => $row['CID'], 
           'Item' => $row['Item'], 
           'Parent' => $row['Parent'] 
          ); 
    } 
    else 
    { 
     $tree[$row['Parent']]['Children'][$row['CID']] = $row['Item']; 
    } 
} 

$count = array_keys($tree); 

foreach ($count as $array) 
{ 
    ksort($tree[$array]['Children']); 
} 

echo "<xmp>".print_r($tree, true)."</xmp>"; 
Смежные вопросы