Вашият код ще генерира само меню на две нива, ако трябва да преминете през всяко ниво, което искате, мисля, че трябва да използвате рекурсия.
Ето пример, базиран на вашата структура на базата данни и проби. В примера ще генерираме меню на различни нива, английските етикети се използват за имена на елементи от менюто.
<?php
$db = new PDO('mysql:host=localhost;dbname=testdb', 'root', '');
function drawMenu($db, $parent, $level = null){
$m = $db->prepare(" SELECT * FROM
administrator_menu, administrator_menu_description
where administrator_menu.id = administrator_menu_description.id
and language_id = 2
and parent_id = $parent");
$m->execute();
foreach ($m->fetchAll() as $menu_row) {
$m = $db->prepare("SELECT count(*) FROM administrator_menu where parent_id = $menu_row[id]");
$m->execute();
// The item is parent, so do recursion again
if($m->fetchAll()[0][0] !== '0' && $level !== 0){
echo "<li>" . $menu_row['label']."<ul>";
drawMenu($db, $menu_row[0], $level - 1);
echo "</ul></li>";
}else{ // The item is a leaf or we reach the end level, i.e. base case, so do print the item label
echo "<li>" . $menu_row['label'] . "</li>";
}
}
}
?>
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<?php
echo "<div> <ul>";
drawMenu($db, 0, null); // all levels
echo "</ul></div>";
echo "--------------------------------------------------------";
echo "<div> <ul>";
drawMenu($db, 0, 0); // level 0
echo "</ul></div>";
echo "--------------------------------------------------------";
echo "<div> <ul>";
drawMenu($db, 0, 1); // level 1
echo "</ul></div>";
echo "--------------------------------------------------------";
echo "<div> <ul>";
drawMenu($db, 0, 2); // level 2
echo "</ul></div>";
?>
</body>
</html>
За да нарисувате всички нива:
echo "<div> <ul>";
drawMenu($db, 0, null); // all levels
echo "</ul></div>";
drawMenu
функцията работи както следва:
- Първо предаваме
$db
обект за извършване на заявки за база данни,$parent
с което дървото ще започне и$level
за нивото на дървото. - Функцията ще стартира, като изберете дъщерното на дадения
$parent
и преминете в цикъл за всеки единforeach ($m->fetchAll() as $menu_row) {...}
. -
В цикъла имаме два случая:
-
Елементът е лист, т.е. не е родител за други елементи, или стигаме до последното ниво на дървото. Този случай се нарича Основен случай , в който рекурсията ще спре и ще върне стойност
echo "<li>" . $menu_row['label'] . "</li>";
-
Елементът е родител, в този случай ние наричаме
drawMenu
функция отново с идентификатор на елемент$menu_row[0]
като родител и$level - 1
за да сте сигурни, че сте спрели, когато достигнете края на нивата.
-
Тествайте кода и го променете, за да отговаря на вашите нужди.