Рекурсивный обход данных из базы

Рейтинг: 0Ответов: 1Опубликовано: 24.03.2015

Вроде тема изъезженная, но вот наткнуться на реализацию не могу.

Есть таблица типовая: ид\имя\ид предка.

Хочу добится такого:

    array
(
    1 => array
    (
        'text' => 'page/index'
        'id' => 4
        'expanded' => false
        'children' => array
        (
            0 => array
            (
                'text' => 'site/index'
                'id' => 5
                'expanded' => false
            )
        )
    )
    4 => array
    (
        'text' => '222'
        'id' => 2
        'expanded' => false
        'children' => array
        (
            0 => array
            (
                'text' => '3'
                'id' => 3
                'expanded' => false
                'children' => array
                (
                    0 => array
                    (
                        'text' => '4'
                        'id' => 7
                        'expanded' => false
                    )
                )
            )
            1 => array
            (
                'text' => '22222'
                'id' => 8
                'expanded' => false
            )
        )
    )

Нужно рекурсивно пробежаться по всем полученным данным и в зависимости, какой ид предка, закинуть в тот массив. У корня ид предка, соотвественно, нулл. Про проход в 2-3-4 захода конечно знаю. Глубина не известна необходима рекурсивная функция.

дамп что имею

    array(9) {
  [0]=>
  array(3) {
    ["id"]=>
    int(3)
    ["text"]=>
    string(1) "3"
    ["parent_id"]=>
    int(2)
  }
  [1]=>
  array(3) {
    ["id"]=>
    int(4)
    ["text"]=>
    string(10) "page/index"
    ["parent_id"]=>
    int(1)
  }
  [2]=>
  array(3) {
    ["id"]=>
    int(5)
    ["text"]=>
    string(10) "site/index"
    ["parent_id"]=>
    int(4)
  }
  [3]=>
  array(3) {
    ["id"]=>
    int(7)
    ["text"]=>
    string(1) "4"
    ["parent_id"]=>
    int(3)
  }

нужно что то вроде этого

function outTree($parent_id, $level) {
global $category_arr; //Делаем переменную $category_arr видимой в функции
if (isset($category_arr[$parent_id])) { //Если категория с таким parent_id существует
    foreach ($category_arr[$parent_id] as $value) { //Обходим
        /**
         * Выводим категорию
         *  $level * 25 - отступ, $level - хранит текущий уровень вложености (0,1,2..)
         */
        echo "<div style='margin-left:" . ($level * 25) . "px;'>" . $value["name"] . "</div>";
        $level = $level + 1; //Увеличиваем уровень вложености
        //Рекурсивно вызываем эту же функцию, но с новым $parent_id и $level
        outTree($value["id"], $level);
        $level = $level - 1; //Уменьшаем уровень вложености
    }
}

}

Ответы

▲ 1
$a = Page::model()->findAll();
foreach ($a as $user)
{
        $all[$user->p_parent][] = array(id => $user->p_id, text=> $user->p_title, parent_id => $user->p_parent);   
}
function RecursiveTree2(&$rs, $parent)
{
    $out = array();
    if (!isset($rs[$parent]))
    {
        return $out;
    }
    foreach ($rs[$parent] as $row)
    {
        $chidls = RecursiveTree2($rs, $row['id']);
        if ($chidls)
        {
            $row['expanded'] = false;
            $row['children'] = $chidls;            
        }
        $out[] = $row;
    }
    return $out;
}
$this->widget('CTreeView', array('data' => RecursiveTree2($all ,0), 'htmlOptions' => array('class' => 'treeview-red')));

дамп массива $all

   array(7) {
  [2]=>
  array(2) {
    [0]=>
    array(3) {
      ["id"]=>
      int(3)
      ["text"]=>
      string(1) "3"
      ["parent_id"]=>
      int(2)
    }
    [1]=>
    array(3) {
      ["id"]=>
      int(8)
      ["text"]=>
      string(5) "22222"
      ["parent_id"]=>
      int(2)
    }
  }