Рекурсия и передача значения переменной

myphp98

Новичок
Добрый день!
Изучаю php не давно. Пытаюсь построить деревья. В БД есть поля id_parent (id родителя), name (название раздела), link (кусок (папка) url-раздела)
Соответственно, путь к подразделу будет складываться, как Раздел родителя + линк самого Подраздела, т.е. /Раздел/Подраздел/
Но как это вывести ума не приложу? Вот сам код по выводу дерева
PHP:
$result = mysql_query("SELECT * FROM categories");

if   (mysql_num_rows($result) > 0){
	$cats = array();
	
	while($cat =  mysql_fetch_assoc($result)) {
		$cats[$cat['id_parent']][] =  $cat;
	}
}



function build_tree($cats,$id_parent){
	if(is_array($cats) and isset($cats[$id_parent])){
		$tree = '<ul>';
		foreach($cats[$id_parent] as $key => $cat){
			$tree .= '<li>'.$cat['name'].' - '.$cat['link'].' - '.$key;
			$tree .=  build_tree($cats,$cat['id']);
			//unset ($sum);
			// Последняя интерация
			if ($cat === end($cats[$id_parent])) {
				$tree .= 'Goo';
			}
			$tree .= '</li>';
		}
		$tree .= '</ul>';
	} else return null;
	return $tree;
}

echo build_tree($cats,0);
 

Фанат

oncle terrible
Команда форума
Не очень понятен вопрос. в чем конкретно проблема?
в примере вроде бы разделы разделяются слешем, а в коде - тегами.
попробуй сформулировать вопрос поточнее
 

myphp98

Новичок
Хорошо, постараюсь, кусок самой таблицы (приблизительно)
id id_parent name link
1 0 Раздел 1 razdel_1
2 1 Подраздел1 podrazdel_1
Соответственно, url к Подразделу1 будет складываться из url хоста $_SERVER[HTTP_HOST], url родителя razdel_1 и url самого подраздела
А вот как передать передать url родителя к "сыну(внуку и т.д.)" не могу понять.
 

Фанат

oncle terrible
Команда форума
урл родителя к внуку передать невозможно. поскольку детей больше чем родителей по определению.
поэтому передать можно только наоборот - поднимаясь от внука к дедушке.
но ребенку можно передать ид родителя.

если исходить из твоей задачи, то рекурсия здесь не нужна.
тебе нужен, как я понимаю, только цикл, который по очереди проходит по частям урла и запрашивает их в БД, получая ид родителя и подставляя его в следующий запрос
 

Lionishy

Новичок
myphp98
Статический стек поможет.
Если ветки (дети) есть, добавляешь родительский url в стек до рекурсивного вызова, убираешь после.
Если веток нет, ничего не добавляешь.
Для каждого элемента url будет складываться из слияния стека в обратном порядке и собственного url.
 

myphp98

Новичок
Сейчас изучаю рекурсию. В книге про нее очень мало что есть. В интернете нашел этот пример. Решил попробовать сделать карту сайта с линками на раздел. Но так чтобы была видна вложенность. Конечно, можно в поле `link` указывать полный путь, но это слишком просто для обучения. Хотя указывая полный путь, я так думаю, можно обойтись без поля id_parent, т.к. в самом url содержится и папа, и дедушка. Сами sql-запросы можно делать через LIKE. Не подскажите, LIKE работает медленнее, чем WHERE? Это так, мне на будущее.
А как организовать цикл? Если можно с примером.
Как думал я (не правильно думал)
PHP:
$tree = '<ul>';
        foreach($cats[$id_parent] as $key => $cat){
            $tree .= '<li>'.$cat['name'].' - '.$cat['link'].' - '.$key;
            // объявляем переменную, а потом передаем ее по ссылке &
            // соответственно первый проход функции, это распечатка разделов самого высокого уровня, а дальше передаем переменную $sum
           $tree .= $sum;
            $sum .= $cat['link']
            $tree .=  build_tree($cats,$cat['id'],&$sum);
            // здесь удаляем переменную
            unset ($sum);
 

myphp98

Новичок
myphp98
Статический стек поможет.
Если ветки (дети) есть, добавляешь родительский url в стек до рекурсивного вызова, убираешь после.
Если веток нет, ничего не добавляешь.
Для каждого элемента url будет складываться из слияния стека в обратном порядке и собственного url.
А можно на примере, примерно так я это и представлял. Пойду почитаю про стеки.
 

Фанат

oncle terrible
Команда форума
Давай-ка знаешь что?
Изложи сначала задачу.
Не тяп-ляп "вот здесь у меня то, а там еще это", а КОНКРЕТНО
- вот у меня такой урл
- вот такую строку я хочу получить
- вот из такой базы данных

а то сейчас, по-моему, ни ты сам не представляешь свою задачу, ни, тем более, мы
 

myphp98

Новичок
Есть таблица в БД, со следующими полями
PHP:
id id_parent name           link
1   0        Раздел1        razdel_1
2   1        Подраздел1     podrazdel_1
Нужно создать карту сайта в виде дерева (с любым уровнем вложенности). На который бы отображались все пункты меню. Все пункты меню должны иметь линк.
P.S. По поводу WHERE и LIKE. Что быстрее работает?
 

Фанат

oncle terrible
Команда форума
Понятно.
а то я отчего-то затупил, и решил, что тебе хлебные крошки нужны, из-за " /Раздел/Подраздел/".
Тогда да - нужна рекурсия.
Пиши рекурсивную функцию, которая
1. берет данные сразу из базы
2. форматирует дерево не ul-ами, тупо nbsp; по количеству уровней вложенности. уровень передаёшь вторым параметром в функцию, после родителя.
 

Lionishy

Новичок
PHP:
function categoryLocatorConstructor($node) {
    static $urlStack = array();
    if( $node->hasChildren() ) {
		array_push($urlStack, $node->getURL());
		foreach($node->getChildren() as $child)
			categoryLocatorConstructor($child);
		array_pop($urlStack);
	}
	$node->setFullURL(
		implode('/',$urlStack).'/'.$node->getURL().'<br />';
	);
}
myphp98
Как-то так... Разные там getChildren setFullURL можно как удобно осуществить. Классом или картой (массивом). Мне лениво.
 

myphp98

Новичок
Если я правильно понял, все же лучше указывать полный путь. В принципе до этого так примерно и делал. Парсил url, потом explode, узнавал уровень вложенности $level, а далее <div style="padding-left:'.$level.'px">Раздел</div>
Спасибо за ответ.
 
Сверху