За последние 24 часа нас посетили 51814 программистов и 1756 роботов. Сейчас ищут 1689 программистов ...

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

Тема в разделе "PHP для новичков", создана пользователем des1roer, 24 мар 2015.

  1. des1roer

    des1roer Новичок

    С нами с:
    10 апр 2014
    Сообщения:
    55
    Симпатии:
    0
    Вроде тема изъезженная, но вот наткнуться на реализацию не могу.
    есть таблица типовая
    ид\имя\ид предка.
    хочу добится такого
    Код (Text):
    1. array
    2. (
    3.     1 => array
    4.     (
    5.         'text' => 'page/index'
    6.         'id' => 4
    7.         'expanded' => false
    8.         'children' => array
    9.         (
    10.             0 => array
    11.             (
    12.                 'text' => 'site/index'
    13.                 'id' => 5
    14.                 'expanded' => false
    15.             )
    16.         )
    17.     )
    18.     4 => array
    19.     (
    20.         'text' => '222'
    21.         'id' => 2
    22.         'expanded' => false
    23.         'children' => array
    24.         (
    25.             0 => array
    26.             (
    27.                 'text' => '3'
    28.                 'id' => 3
    29.                 'expanded' => false
    30.                 'children' => array
    31.                 (
    32.                     0 => array
    33.                     (
    34.                         'text' => '4'
    35.                         'id' => 7
    36.                         'expanded' => false
    37.                     )
    38.                 )
    39.             )
    40.             1 => array
    41.             (
    42.                 'text' => '22222'
    43.                 'id' => 8
    44.                 'expanded' => false
    45.             )
    46.         )
    47.     )
    нужно рекурсивно пробежаться по всем полученным данным и в зависимости какой ид предка закинуть в тот массив. у корня ид предка соотвественно нулл
     
  2. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.600
    Симпатии:
    1.764
    Есть множество методов хранить в БД древовидные структуры, работающих эффективнее. Nested Sets, к примеру. И множество готовых реализаций.
     
  3. des1roer

    des1roer Новичок

    С нами с:
    10 апр 2014
    Сообщения:
    55
    Симпатии:
    0
    Nested Sets не очень актуален. для такого как я понимаю тоже много реализаций.
    нужно просто под конкретный пример адаптировать например это
    Код (Text):
    1. function getCategory() {
    2.     $query = mysql_query("SELECT * FROM `category`");
    3.     $result = array();
    4.     while ($row = mysql_fetch_array($query)) {
    5.         $result[$row["parent_id"]][] = $row;
    6.     }
    7.     return $result;
    8. }
    9.  
    10. //В переменную $category_arr записываем все категории
    11. $category_arr = getCategory();
    12.  
    13. /**
    14.  * Вывод дерева
    15.  * @param Integer $parent_id - id-родителя
    16.  * @param Integer $level - уровень вложености
    17.  */
    18. function outTree($parent_id, $level) {
    19.     global $category_arr; //Делаем переменную $category_arr видимой в функции
    20.     if (isset($category_arr[$parent_id])) { //Если категория с таким parent_id существует
    21.         foreach ($category_arr[$parent_id] as $value) { //Обходим
    22.             /**
    23.              * Выводим категорию
    24.              *  $level * 25 - отступ, $level - хранит текущий уровень вложености (0,1,2..)
    25.              */
    26.             echo "<div style='margin-left:" . ($level * 25) . "px;'>" . $value["name"] . "</div>";
    27.             $level = $level + 1; //Увеличиваем уровень вложености
    28.             //Рекурсивно вызываем эту же функцию, но с новым $parent_id и $level
    29.             outTree($value["id"], $level);
    30.             $level = $level - 1; //Уменьшаем уровень вложености
    31.         }
    32.     }
    33. }
    34.  
    35. outTree(0, 0);
    36.  
    37. ?>
    только я вот с yii мучаюсь и у меня $a[$i]['p_parent'] , $a[$i]['p_id'] и $a[$i]['p_title']
     
  4. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.600
    Симпатии:
    1.764
    Покажите структуру базы данных. Но, а - это неэффективно, б - запаритесь с рекурсией, в - тяжело избежать рекурсивного обращения к базе данных, т.е. медленных запросов. Я в одном проекте делал по этой статье: http://abramov.tv/2009/09/postroenie-dereva-iz-bd-na-php/, но во время этого проекта меня достало делать рекурсивные функции по любому поводу, поэтому в следующем я уже взял Nested Sets.

    Добавлено спустя 2 минуты 34 секунды:
    А вообще, ваш вопрос не въехал. Чужой код вы привели несложный
     
  5. des1roer

    des1roer Новичок

    С нами с:
    10 апр 2014
    Сообщения:
    55
    Симпатии:
    0
    имею
    Код (Text):
    1.   array(9) {
    2.   [0]=>
    3.   array(3) {
    4.     ["id"]=>
    5.     int(3)
    6.     ["text"]=>
    7.     string(1) "3"
    8.     ["parent_id"]=>
    9.     int(2)
    10.   }
    11.   [1]=>
    12.   array(3) {
    13.     ["id"]=>
    14.     int(4)
    15.     ["text"]=>
    16.     string(10) "page/index"
    17.     ["parent_id"]=>
    18.     int(1)
    19.   }
    20.   [2]=>
    21.   array(3) {
    22.     ["id"]=>
    23.     int(5)
    24.     ["text"]=>
    25.     string(10) "site/index"
    26.     ["parent_id"]=>
    27.     int(4)
    28.   }
    29.   [3]=>
    30.   array(3) {
    31.     ["id"]=>
    32.     int(7)
    33.     ["text"]=>
    34.     string(1) "4"
    35.     ["parent_id"]=>
    36.     int(3)
    37.   }
     
  6. des1roer

    des1roer Новичок

    С нами с:
    10 апр 2014
    Сообщения:
    55
    Симпатии:
    0
    Код (Text):
    1. $a = Page::model()->findAll();
    2. foreach ($a as $user)
    3. {
    4.         $all[$user->p_parent][] = array(id => $user->p_id, text=> $user->p_title, parent_id => $user->p_parent);  
    5. }
    6. function RecursiveTree2(&$rs, $parent)
    7. {
    8.     $out = array();
    9.     if (!isset($rs[$parent]))
    10.     {
    11.         return $out;
    12.     }
    13.     foreach ($rs[$parent] as $row)
    14.     {
    15.         $chidls = RecursiveTree2($rs, $row['id']);
    16.         if ($chidls)
    17.         {
    18.             $row['expanded'] = false;
    19.             $row['children'] = $chidls;            
    20.         }
    21.         $out[] = $row;
    22.     }
    23.     return $out;
    24. }
    25. $this->widget('CTreeView', array('data' => RecursiveTree2($all ,0), 'htmlOptions' => array('class' => 'treeview-red')));
    дамп массива
    Код (Text):
    1. array(7) {
    2.   [2]=>
    3.   array(2) {
    4.     [0]=>
    5.     array(3) {
    6.       ["id"]=>
    7.       int(3)
    8.       ["text"]=>
    9.       string(1) "3"
    10.       ["parent_id"]=>
    11.       int(2)
    12.     }
    13.     [1]=>
    14.     array(3) {
    15.       ["id"]=>
    16.       int(8)
    17.       ["text"]=>
    18.       string(5) "22222"
    19.       ["parent_id"]=>
    20.       int(2)
    21.     }
    22.   }
     
  7. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.600
    Симпатии:
    1.764
    Которого из?

    Добавлено спустя 1 минуту 32 секунды:
    А почему в исходном массиве нет ни одного элемента с parent_id=0?