Вроде тема изъезженная, но вот наткнуться на реализацию не могу. есть таблица типовая ид\имя\ид предка. хочу добится такого Код (Text): 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 ) ) ) нужно рекурсивно пробежаться по всем полученным данным и в зависимости какой ид предка закинуть в тот массив. у корня ид предка соотвественно нулл
Есть множество методов хранить в БД древовидные структуры, работающих эффективнее. Nested Sets, к примеру. И множество готовых реализаций.
Nested Sets не очень актуален. для такого как я понимаю тоже много реализаций. нужно просто под конкретный пример адаптировать например это Код (Text): function getCategory() { $query = mysql_query("SELECT * FROM `category`"); $result = array(); while ($row = mysql_fetch_array($query)) { $result[$row["parent_id"]][] = $row; } return $result; } //В переменную $category_arr записываем все категории $category_arr = getCategory(); /** * Вывод дерева * @param Integer $parent_id - id-родителя * @param Integer $level - уровень вложености */ 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; //Уменьшаем уровень вложености } } } outTree(0, 0); ?> только я вот с yii мучаюсь и у меня $a[$i]['p_parent'] , $a[$i]['p_id'] и $a[$i]['p_title']
Покажите структуру базы данных. Но, а - это неэффективно, б - запаритесь с рекурсией, в - тяжело избежать рекурсивного обращения к базе данных, т.е. медленных запросов. Я в одном проекте делал по этой статье: http://abramov.tv/2009/09/postroenie-dereva-iz-bd-na-php/, но во время этого проекта меня достало делать рекурсивные функции по любому поводу, поэтому в следующем я уже взял Nested Sets. Добавлено спустя 2 минуты 34 секунды: А вообще, ваш вопрос не въехал. Чужой код вы привели несложный
имею Код (Text): 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) }
Код (Text): $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'))); дамп массива Код (Text): 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) } }
Которого из? Добавлено спустя 1 минуту 32 секунды: А почему в исходном массиве нет ни одного элемента с parent_id=0?