Hallo allemaal,
Ik ben een code aan het omzetten van een HTML code naar een PHP die alles uit een database haalt.
De code bevat een stukje de het menu moet tonen. Met behulp van <li> en <lu>
Nu lukt het mij niet om de submenu's er in te krijgen.
Hieronder staan eerst de HTML code zoals die is, dan hoe die door de PHP code wordt gemaakt en als derde de php code die de html code moet maken.

Wie weet er wat ik fout doe?

html-code moet ongeveer dit zijn

<li><a href="inkomsten-uitgaven.html" class="active">inkomsten &amp; uitgaven</a></li>
<li><a href="beheer.html">beheer</a>
     <ul>
          <li><a href="b-t-w.html">b.t.w.</a></li>
     </ul>
</li>
<li><a href="administraties.php">administraties</a>
     <ul>
	  <li><a href="administratie.php">nieuwe administratie</a></li>
     </ul>
</li>


Deze html-code wordt genereerd!

<li><a href="inkomsten-uitgaven.html" class="active">inkomsten &amp; uitgaven</a></li>
<li><a href="beheer.html">beheer</a></li>
<li><a href="administraties.php">administraties</a></li>


Hier onder volgt mijn php code

<?php 	// *** menu **** 
		// menu ombouwen naar database menu
	$menu_query1 = "SELECT * FROM tabel_menu WHERE menu_sub_van = 0 ORDER BY menu_waarde ASC";
	$menu_result1 = mysqli_query($connect, $menu_query1);
	$menu_count1 = mysqli_num_rows($menu_result1);
	$num_row = 0;
	while ($menu_row1 = mysqli_fetch_array($menu_result1, MYSQLI_ASSOC)) {

		$num_row ++;
		$menu_plaatsen[$num_row] = "<li><a href='" . $menu_row1['menu_link'] . "' class='active'>" . $menu_row1['menu_tekst'] . "</a>";
		
		$menu_query2 = "SELECT * FROM tabel_menu WHERE menu_waarde = " . $menu_row1['menu_sub_van'] . " ORDER BY menu_waarde ASC";
		$menu_result2 = mysqli_query($connect, $menu_query2);
		$menu_count2 = mysqli_num_rows($menu_result2);
		
		if ($menu_count2 == 0) {
			$num_row ++;
			$menu_plaatsen[$num_row] = "</li>";
		} else { //$menu_count2 >> 0 dus er zijn geen submenu's
		
			$num_row ++;
			$menu_plaatsen[$num_row] = "<ul>";
			while ($menu_row2 = mysqli_fetch_array($menu_result2, MYSQLI_ASSOC)) {
				$num_row ++;
				$menu_plaatsen[$num_row] = "<li><a href='" . $menu_row2['menu_link'] . ">" . $menu_row2['menu_tekst'] . "</a></li>";
				$num_row ++;
			}
			$menu_plaatsen[$num_row] = "</ul>";
			mysqli_free_result($menu_result2);
			
			$num_row ++;
			$menu_plaatsen[$num_row] = "</li>";		
		}
	}			
	mysqli_free_result($menu_result1);

		
?>

<nav class="art-nav">
	<ul class="art-hmenu">
		<?php 
			foreach ($menu_plaatsen as $plaatsen){
				echo($plaatsen);
			}
		?>
	</ul> 
</nav>

<?php // *** einde menu **** 
?>
Zo zo.... dat is nog eens een uitleg.
Ik heb inderdaad alles al in de juiste volgorde staan. Dat doe ik door het veld 'menu_sub_van' te gebruiken om aan te geven onder welk menu hij hoort, en 'menu_waarde' bepaal ik de hoogte in het menu. De items die het hoofdmenu vormen, hebben bij 'menu_sub_van' de waarde 0.
Als er een submenu is, vul ik daar de waarde in die bij de hoofdmenu-items bij 'menu_waarde' is ingevuld.

Door ORDER BY te gebruiken, levert de query alles in de juiste volgorde aan. Het blijft natuurlijk wel dat de data die ik in geef, goed moet worden ingegeven. Anders staat het menu door elkaar. Maar dat heeft verder niets met de werking van de code te maken.

Mijn probleem zit hem in het vullen van de array.

Misschien daarna nog wel meer, maar dat durf ik nu niet te zeggen. Ik dank dat het dan wel gaat lukken.
Want als het goed is zou bij een op de juiste manier gevulde array, de code moeten werken.
Over welke array heb je het, waar je op vast loopt?
Heb je voorbeeld even aangepast, het volgende zou moeten werken. Je overschreef trouwens elke stap van de loop $myItems, dus dat ging sowieso niet werken :p.

Dit zou in grote lijnen moeten werken, hierbij bouw ik rechtstreeks de boom, zonder "myItems" in een apart array te zetten:
<?php
$query =
    "SELECT menu_id, menu_tekst, menu_waarde, menu_sub_van, menu_link, menu_reg_date
    FROM tabel_menu
    ORDER BY menu_sub_van, menu_waarde";

$result = mysqli_query($connect, $query);

// NB dit is automatisch het element op index 0, het root-element, je zou dit ook expliciet kunnen doen met 0 => array(...)
$myTree = array(
    array(
        'data'     => 'root',
        'parent'   => false, // of NULL, of wat dan ook, de root heeft geen parent
        'children' => array(),
    ),
);

while ($row = mysqli_fetch_assoc($result)) {
    // maak het huidige tree-item aan
    $myTree[$row['menu_id']] = array(
        'parent'   => $row['menu_sub_van'], // niet echt nodig om toe te voegen, maar kan handig zijn
        'data'     => $row['menu_tekst'],
        'children' => array(), // initialiseer children als leeg array
    );

    // voeg het huidige item toe als child van de parent :)
    // de query zou door de sorteervolgorde moeten garanderen dat het parent-element - $myTree[$row['menu_sub_van']] - reeds bestaat
    $myTree[$row['menu_sub_van']]['children'][] = $row['menu_id'];
}

// de rest als voorheen
?>

Overigens, als de parent (menu_sub_van) NULL is, wat mogelijk handig kan zijn als je een relationele database hebt en een foreign key wilt maken die naar zichzelf (dezelfde tabel) wijst, dan zou je deze om moeten zetten naar 0 ingeval het het root-element betreft (of wat je voor index voor het root-element gekozen hebt - ook dit kun je vangen in een variabele zodat je dit maar op 1 plaats hoeft aan te passen), dus zoiets voor alle code:
<?php
$parent = ($row['menu_sub_van'] === NULL ? 0 : $row['menu_sub_van']);
?>

En vervolgens refereer je overal aan de parent via $parent in plaats van $row['menu_sub_van']. Dit werk mogelijk ook beter voor de leesbaarheid.

Ten overvloede:
<?php
$rootId = 0; // definieer deze variabele op 1 plek zodat je deze ook maar op 1 plaats hoeft aan te passen

$myTree = array(
    $rootId => array(
        'data'     => 'root',
        'parent'   => NULL,
        'children' => array(),
    ),
);

while ($row = mysqli_fetch_assoc($result)) {
    $parent = ($row['menu_sub_van'] === NULL ? $rootId : $row['menu_sub_van']);
    $myTree[$row['menu_id']] = array(
        'parent'   => $parent,
        'data'     => $row['menu_tekst'],
        'children' => array(),
    );

    $myTree[$parent]['children'][] = $row['menu_id'];
}
?>


En weer op eenzelfde wijze zou je $row['menu_id'] kunnen vangen in een variabele $currentId ofzo.

Deze regel wordt dan ook meteen (nog) beter leesbaar:
<?php
$myTree[$parent]['children'][] = $currentId;
?>

En dat illustreert weer het belang van een goede naamgeving voor (en de introductie van hulp)variabelen.
Het is gelukt.
Ik heb het een en ander aangepast en wat gevogeld.
Eerder leerde ik dat PHP en HTML code zo veel mogelijk gescheiden dient te worden. Dus beginnen met PHP en daarna de HTML met een minimum aan PHP code. Dus die les heb ik goed onthouden en hier verwerkt.
Allemaal erg bedankt voor deze nieuwe lessen.

De code hier onder, is de uiteindelijke code. Het werkt.


<?php 	// *** menu **** 
$query =
    "SELECT menu_id, menu_tekst, menu_waarde, menu_sub_van, menu_link, menu_reg_date
    FROM tabel_menu
    ORDER BY menu_sub_van, menu_waarde";

$result = mysqli_query($connect, $query);

// NB dit is automatisch het element op index 0, het root-element, je zou dit ook expliciet kunnen doen met 0 => array(...)
$rootId = 0; // definieer deze variabele op 1 plek zodat je deze ook maar op 1 plaats hoeft aan te passen

$myTree = array(
    $rootId => array(
        'data'     => 'root',
        'parent'   => NULL,
		'link' => NULL,
        'children' => array(),
    ),
);

while ($row = mysqli_fetch_assoc($result)) {
    $parent = ($row['menu_sub_van'] === NULL ? $rootId : $row['menu_sub_van']);
    // maak het huidige tree-item aan
    $myTree[$row['menu_waarde']] = array(
        'parent'	=> $parent, // niet echt nodig om toe te voegen, maar kan handig zijn
        'data'		=> $row['menu_tekst'],
        'link' 		=> $row['menu_link'],
		'children' => array(), // initialiseer children als leeg array
    );

    // voeg het huidige item toe als child van de parent :)
    // de query zou door de sorteervolgorde moeten garanderen dat het parent-element - $myTree[$row['menu_sub_van']] - reeds bestaat
    $myTree[$parent]['children'][] = $row['menu_waarde'];
}

// weergavefunctie
function displayTree($tree, $index) 
{
    if ($index == 0) { 
		echo "<ul class='art-hmenu'>";
	}
	else
	{
		echo "<ul>";
	}
	
	foreach ($tree[$index]['children'] as $child) 
	{
        echo "<li><a href='".$tree[$child]['link']."'>".$tree[$child]['data']."</a>"; 
		if (count($tree[$child]['children']) > 0) 
		{
			displayTree($tree, $child);
		}
        echo "</li>";
    }
	echo "</ul>";
}
?>

<nav class="art-nav">
	<?php 
		// weergave
		if (count($myTree) > 0) 
		{
				displayTree($myTree,0);
		}	
	?>
</nav>

Fijn dat het werkt. Al zou ik liever in de databasestructuur logische benaming gebruiken als ParentID, om in het stramien van je script te blijven. ;-)

Reageren