Структурирование разделов сайта при написании CMS

CompAS

Новичок
Структурирование разделов сайта при написании CMS

Пишу CMS. Разделы сайта хранятся в БД как записи. У каждого раздела есть поля id и pid (id родителя).
Встала задача структурирования разделов. Из исходного массива неупорядоченных записей нужно получить массив записей главных разделов (не имеющих pid). Каждый раздел нового массива должен содержать массив children, в котором будут находиться записи его подразделов, извлечённые из исходного массива. В свою очередь, каждый подраздел должен иметь свой массив children и т.д.
Захотел решить задачу методом рекурсии. Для этого написал 2 функции.

PHP:
function StructureSections (&$hash) {
	
	// Извлекаем из входного массива разделы, не имеющие родительских разделов
	// функция getElementsByValue работает 100%
	$hash_ = getElementsByValue($hash,"pid",false);
	
	foreach ($hash_ as $n => $section) GetChildren($hash_[$n],$hash);
	
	$hash = $hash_;
}

function GetChildren (&$section, &$arr) {
	
	foreach ($arr as $n => $sec):
		
		if ($sec['pid'] == $section['id']):
			
			GetChildren($sec,$arr);
			
			$section['children'][] = $sec;

		endif;
	
	endforeach;
}
Проблема. Если подраздел находится (выполняется условие $sec['pid'] == $section['id']), запускается новая функция GetChildren, а "по возвращении" в первую функцию GetChildren цикл foreach не продолжается. То есть первый найденный подраздел записывается в $section['children'][0], а до других подразделов очередь не доходит.

Если закомментировать строчку GetChildren($sec,$arr), все подразделы первого уровня, естественно, находятся, но исчезает рекурсия, поэтому подразделы второго уровня не обрабатываются.

Подскажите, как решить проблему.
 

Groove

Новичок
>>Пишу CMS. Разделы сайта хранятся в БД как записи. У каждого раздела есть поля id и pid (id родителя).
>>Встала задача структурирования разделов.
прямо просится NestedSets...
 

CompAS

Новичок
задача решена. в параметрах функции GetChildren нужно убрать & перед $arr.
проблема была в том, что так как массив передавался по ссылке, по возвращении в начало рекурсии указатель его смещался на конец и цикл foreach останавливался.
с другой стороны, передача копии исходного массива не позволит удалять из него найденные элементы, чтобы таким образом следующие итерации проходили быстрее. но здесь ещё буду думать.
спасибо откликнувшимся. ваши ответы стимулировали желание более тщательной отладки.
 
Сверху