Вложенные массивы и навигация по базе данных

predator

web designer
Вложенные массивы и навигация по базе данных

PHP:
// Имеем древообразную базу данных - цель сгенерить меню вида
// val1
// val2
// val3
//   val1
//   val2
//   val3
//   val4
// val4
// val5
// для этого:
// получили путь от кликнутого узла - к родоначальнику
$result = db_query("SELECT id, lft, rgt, level FROM articles WHERE $article_info[lft] BETWEEN lft AND rgt ORDER BY level ASC");
// получаем детишек всех узлов - вплоть до детей родоначальника и пишем их в массив
while($row = mysql_fetch_array($result)) {
	$level_plus = $row['level']+1;
	$child = db_query("SELECT id, title FROM articles WHERE lft BETWEEN $row[lft] AND $row[rgt] AND level=$level_plus");
// проблема в генерации вложенного массива с перечнем пунктов меню
// раньше с вложенными не работал вот наваял, но видимо не правильно 
// помогите кто сможет
	while($str = mysql_fetch_array($child)) {
		if(!isset($id_pred))$id_pred=$row['id'];
		if($str['id']==$id_pred){
			$arr= array($str['id'] => $arr_pred);}
		else
			$arr= array($str['id'] => $str['title']);
	}
	$id_pred=$row['id'];
	$arr_pred=$arr;
}
// выводим массив
while (list($key, $val) = each($arr)) {
	echo("<a href=\"index.phtml?type=20&id=$key\">$val</a>");
}

// запросы к базе рабочие, проверено, их можно не обсуждать - главное в массивах разобраться
 

predator

web designer
хм, это понятно (я ман читал :)) а вот как это реализовать в моём случае (когда надо запихать данные от запросов в массив вложенность которого заранее неизвесна)
 

Kornet

Guest
А обязательно всё впихивать в массив? Возможно можно сразу строить меню?
 

predator

web designer
2Kornet: да ты прав можно обойтись наверно без массива
2tony2001: видимо надо рекурсию использовать, но как?
 

Kornet

Guest
Если кого то интересует, то я мог бы описать реализацию древовидного меню, на примере http://www.motorzavod.com. Если нет, то на нет и суда нет.
 

predator

web designer
я тут пробовал дома - без массива получается только меню вида:
val1
val2
val3
&nbsp;val1
&nbsp;val2
&nbsp;&nbsp;val1
&nbsp;&nbsp;val2
что не подходит (теряется древообразность)
в то - же время в массив запихнуть не получается - код:
PHP:
// получили путь от кликнутого узла к корню
$result = db_query("SELECT id, lft, rgt, level FROM articles WHERE $article_info[lft] BETWEEN lft AND rgt ORDER BY level ASC");
// получаем детишек всех узлов - вплоть до детей корня и пакуем это всё в массив
while($row = mysql_fetch_array($result)) {
	$only_child = $row['level']+1; // не дальше детей
	for($i=1; $i<=$row['level']; $i++)$nb .="&nbsp;"; // отступы тем больше чем ближе к листкам
	$child = db_query("SELECT id, title FROM articles WHERE lft BETWEEN $row[lft] AND $row[rgt] AND level=$only_child");
                $a=1;
	while($str = mysql_fetch_array($child)) {
		if($str['id']==$_GET['id'])$elem="$nb$str[title]<br>"; // выбранный пункт
		else $elem="$nb<a href=\"index.phtml?type=20&id=$str[id]\">$str[title]</a><br>"; // остальные
		// генерим вложенный массив
		if($str['id']==$id_pred){$arr[$a] = $elem; $a++; $arr[$a] = $arr_pred;} //
		else $arr[$a] = $elem;
		echo $arr[$a];
		$a++;
	}
	$id_pred=$row['id'];
	$arr_pred=$arr;
}
// выводим массив
while (list($key, $val) = each($arr)) {
	echo $val;
}
в результате получается вроде одномерный массив а как вложенный генерить ?
 

Demiurg

Guest
Есть такое понятие, как отладка. За тебя её делать никто не будет.
 

predator

web designer
еслиб я сам отладку не делал, то я бы до такого не добрался :)
всё это понятно - просто я со вложенными массивами ещё не стралкивался...
 

predator

web designer
с генерацией вроде разобрался. Получается массив $arr, один из элементов которого имеет тип array и т.д.
теперь как мне его вывести в виде дерева как я хотел (см.1 сообщение)? Как я понимаю надо рекурсивную функцию. Вот я написал кое-что но не работает. Может кто видит в чём ошибка?
PHP:
function show_array($arr)
while (list($key, $val) = each($arr)) {
	if(gettype($val)=="array") {show_array($val);}
	echo $val;
}
show_array($arr);
 

vladis

Guest
function show_array($arr)
while (list($key, $val) = each($arr)) {
if(gettype($val)=="array") {show_array($val);}
echo $val;
}
show_array($arr);


Как минимум, тебе не хватает {} вокруг тела функции (непонятно как оно вообще воркает). А во-вторых, там случаем, не должно быть "else" перед "echo"?
 

predator

web designer
2leosha: посмотрел, внешне наверно будет похоже но у меня база построена на Вложенных Множествах и такая функция как у тебя не прокатит (хотя она тоже рекурсивная)
2Demiurg: не работало из-за нехватки {}, как сказал vladis
теперь задам идиотский вопрос :)
как из этого:
PHP:
function show_array($arr){
while (list($key, $val) = each($arr))
 {
 if(is_array($val))
  {
  while (list($key, $q) = each($val))
   {
   if(is_array($q))
    {
    while (list($key, $w) = each($q))
     {
     if(!is_array($w))echo "&nbsp;&nbsp;".$w;
     }
    }
   if(!is_array($q))echo "&nbsp;".$q;
   }
  }
 if(!is_array($val))echo $val;
 }
}
сделать рекурсию? :) сразу вот так, в лоб

PS.
Не удивляйтесь на непоследовательность вопросов в этой теме - я задаю вопрос и сам пытаюсь его решить тоже, когда дохожу до очередного струпора задаю следующий вопрос :D
 

Demiurg

Guest
У тебя же есть работающая рукурсионная функция, что в ней не устраивает ?
 

predator

web designer
2Demiurg: да, есть :D - загнался я, что-то...
Есть последний вопрос на эту тему:
PHP:
function show_array($arr, $nb){
  while (list($key, $val) = each($arr)) {
    if(is_array($val)){$nb .="&nbsp;"; show_array($val, $nb);}
    else{echo $nb.$val;}
  }
}
эта функция генерит меню в таком виде
val1.1
val1.2
&nbsp;&nbsp;val2.1
&nbsp;&nbsp;val2.2
&nbsp;&nbsp;val2.3
&nbsp;&nbsp;val1.3
&nbsp;&nbsp;val1.4
как интересно уменьшить количество пробелов чтобы было так:
val1.1
val1.2
&nbsp;&nbsp;val2.1
&nbsp;&nbsp;val2.2
&nbsp;&nbsp;val2.3
val1.3
val1.4

? или как ещё можно отступы генерировать?
 

Demiurg

Guest
Идея правильная, но у тебя в цыкле получается постоянное приращение $nb, а тебе надо, то бы в функции она оставаласm постоянной:
if(is_array($val))show_array($val, "&amp;nbsp;".$nb);
 
Сверху