Выводим древовидное меню с сохранением вложенности

Статья на тему любимого PHPНедавно на работе мне была поставлена задача создать меню, древовидного типа , с сохранением уровней вложенности. Конечно можно было бы просто вывести все меню в раскрытом виде, с помощью рекурсии. Затем написать JavaScript код который бы собирал его и открывал по нажатию. Но мне этот вариант почему то не понравился. Пришлось писать. Сначало ломал голову как дать знать скрипту что он находится в определенном разделе и что раздел тоже вложенный и у него есть родительский пункт. Решение было как всегда простым.

Принцип таков:

Запускаем рекурсивную функцию которая проверяет в каком пункте меню находится пользователь . Она возвратит номера всех вхождений меню (всех родительских меню). А далее  путем другой рекурсивной функции выводим все эти меню.


function IsMyParent($id)// возвращает айдишки всех пунктов меню в которые входит пункт меню выбранный пользователем
{
$sql = "SELECT pid FROM menu WHERE `id`='".(int)$id."' LIMIT 1";
$query = mysql_query($sql);
$ids = array();
$ids[]=$id;

while ($result=mysql_fetch_object($query))
{
if ($result->pid>0){
$ids[] = $result->pid;
}

if ($result->pid>0){

$sql = "SELECT * FROM menu WHERE `id`='".$result->pid."' LIMIT 1";
$query = mysql_query($sql);

if (mysql_num_rows($query)>0)
{
IsMyParent($result->pid);
}
}

}

asort($ids);

return $ids;
}
function tree_show ($sub=0,$level,$menu_id,$ids=array())
{

$sql = "SELECT * FROM menu WHERE pid='".(int)$sub."' ";
$query = mysql_query($sql);
if($level==0){echo '<ul id="nav">';}
IsMyParent($menu_id);

while ($row = mysql_fetch_array($query))
{

echo '<li>';
echo '<a href=';
echo "/index.php?menu=".$row[id];
echo ' >';
echo $row['menu_name'];
echo '</a>';
foreach ($ids as $key=>$val)
{

if ($row['id']==$val){

$sql2 = "SELECT * FROM menu WHERE  pid=".$row['id'];

$query2 = mysql_query($sql2);

$row2 = mysql_num_rows($query2);

if ($row2!==0){
++$level;
echo '<ul>';
tree_show($row['id'],$level,$menu_id);--$level;
echo '</ul>';
}

}

}
echo '</li>';
}

if($level==0){echo '</ul>';}

}

Сразу хотел бы дать и таблицу для этого меню


CREATE TABLE `menu` (
`id` int(11) unsigned NOT NULL auto_increment,
`menu_name` tinytext NOT NULL,
`title` text NOT NULL,
`content` text,
`pid` int(11) default '0',
`hide` int(11) NOT NULL,
`active` int(11) NOT NULL,
PRIMARY KEY  (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=98 DEFAULT CHARSET=utf8 AUTO_INCREMENT=98 ;

И на последок вызываем функцию:

tree_show(0,0,$_GET['menu']);

Мы получили полноценное древовидное меню на PHP.

3 Ответы на “Выводим древовидное меню с сохранением вложенности”

  1. Алексанр, в pid — записывается значение родительского id.
    hide и active — это вспомогательные элементы. Они служат для скрытия и соответственно отображения пункта меню. Для активации и деактивации. Они НЕ являются обязательными.

  2. все можно в один запрос и короче. получить все, разбить на группы по pid и с помощью цыклов собрать, а сортировать средствами базы. иногда просто — это правильнее.

Добавить комментарий