Очень нужна помощь с выводом дерева на PHP

M2
На сайте с 11.01.2011
Offline
342
993

Здравствуйте, люди добрые и не добрые :)))

К этому сообщению прикладываю скрин базы, на котором видно, что дерево не обычное, а со спутанными номерами. Т.е. нет индекса, а номера идут как попало. Так и будет, ибо это экспорт из 1C. Вопрос только в следующем: мне нужно вывести меню, на это меню конечно не всё выводить (там порядка 6000 позиций) а вывести только главные пункты. Т.е. грубо говоря так: нужно вывести пункты у которых rodit_kod равно нулю и все потомки этих пунктов, но только второго уровня. Т.е. вот так:

--Пункт 1

---Подпункт 1

---Подпункт 2

---Подпункт 3

Вот этого уже не надо, хотя это есть в базе:
----Элемент 1 подпункта 3
----Элемент 2 подпункта 3
----Элемент 3 подпункта 3

--Пункт 2

--Пункт 3

--Пункт 4

Буду благодарен за любую помощь в решении данного вопроса.

jpg 92288.jpg
------------------- Крутые VPS и дедики. Качество по разумной цене ( http://cp.inferno.name/view.php?product=1212&gid=1 ) VPS25OFF - скидка 25% на первый платеж по ссылке выше
M2
На сайте с 11.01.2011
Offline
342
#1

Вот этот скрипт замечательно всё делает с одним НО: он выводит ВСЮ структуру дерева, а мне нужны только первые два уровня :(


//1. Загружаем данные. Загружаем в таком виде, в каком они записаны в таблице.

$a_tree=array();
//Ключ массива - идентификатор родительского элемента
// значение - список дочерних элементов

//Загружаем сразу все дерево одним запросом
$r=mysql_query("
select elem_id, rodit_kod, name from test_price
order by name");
//Обратите внимание, что в запросе строки отсортированы по s_name.
//Это сделано для того, что бы и сами элементы массива $a_tree и
// списки дочерних элементов этого массива были отсортированы по этому полю.
for($i=0;$i<mysql_num_rows($r);$i++)
{
$f=mysql_fetch_assoc($r);
if(empty($a_tree[$f['rodit_kod']]))
$a_tree[$f['rodit_kod']]=array();
$a_tree[$f['rodit_kod']][]=$f;
}

//2. Выводим данные.

// Поскольку глубина дерева у нас не ограничена, то логичнее всего
// для вывода использовать рекурсивную функцию.
// Если используемый Вами шаблонный движок это позволяет, то можно
// использовать рекурсивный шаблон.

//Обратите внимание на символ "&" перед аргументом $a_tree.
//Я использовал его для того, что бы при каждом рекурсивном вызове
// php не выделял новую память и не копировал туда весь массив $a_tree,
// а только передавал ссылку на исходный массив.
function tree_print(&$a_tree,$k_parent=0)
{
//условие завершения рекурсии
//Условие, при котором функция никогда не вызывает сама себя

//функция empty() - вернет ложь во всех нужных нам случаях:
// - элемент массива не определен
// - элемент массива определен, но является пустым массивом
if(empty($a_tree[$k_parent])) return;

$t = count($a_tree[$k_parent]);
$rr = $t-1;
echo "<ul>";
for($i=0;$i<$rr;$i++)
{
echo "<li>".$a_tree[$k_parent][$i]['name'];
//рекурсивный вызов - список всех дочерних элементов нужно вставить
// именно в этом месте:
// <li>название
// ** тут список дочерних элементов, он показывается рекурсивным вызовом **
// </li>
tree_print($a_tree,$a_tree[$k_parent][$i]['elem_id']);
echo "</li>";
}
echo "</ul>";
}

//Показываем все дерево:
tree_print($a_tree);
C
На сайте с 04.02.2005
Offline
277
#2

$maxlevel =3;
$cuurentlevel =0;
// здесь вызвать tree_print

function tree_print(&$a_tree,$k_parent=0)
{global $maxlevel, $currentlevel;

if ($maxlevel < $currentlevel) return;
//условие завершения рекурсии
//Условие, при котором функция никогда не вызывает сама себя

//функция empty() - вернет ложь во всех нужных нам случаях:
// - элемент массива не определен
// - элемент массива определен, но является пустым массивом

if(empty($a_tree[$k_parent])) return;

$t = count($a_tree[$k_parent]);
$rr = $t-1;
echo "<ul>";
for($i=0;$i<$rr;$i++)
{
echo "<li>".$a_tree[$k_parent][$i]['name'];
//рекурсивный вызов - список всех дочерних элементов нужно вставить
// именно в этом месте:
// <li>название
// ** тут список дочерних элементов, он показывается рекурсивным вызовом **
// </li>
$currentlevel =$currentlevel +1;
tree_print($a_tree,$a_tree[$k_parent][$i]['elem_id']);
$currentlevel =$currentlevel -1;
echo "</li>";
}
echo "</ul>";
}

Приблизительно так

Chukcha добавил 25.06.2011 в 11:09

возможно избавиться от объявления global;

function tree_print(&$a_tree,$k_parent=0, $maxlevel)
{static $currentlevel =0;
....
$currentlevel++;
tree_print($a_tree,$a_tree[$k_parent][$i]['elem_id']);
$currentlevel--;

}
M2
На сайте с 11.01.2011
Offline
342
#3

Блин, я вот как-то добился, но не знаю, так можно или нет....

Короче в базе есть поле level, так вот я запрос составил такой:


select elem_id, rodit_kod, name from test_price order where level in (1, 2) by name

вроде бы работает :)

Авторизуйтесь или зарегистрируйтесь, чтобы оставить комментарий