[PHP / MySQL] Multilevel menu wordt niet goed uitgelezen

Pagina: 1
Acties:
  • 116 views sinds 30-01-2008
  • Reageer

Onderwerpen


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Ik heb een multilevel menu gemaakt in een MySQL database dat helaas niet goed wordt uitgelezen door mijn PHP scriptje, deze blijft onbedoeld namelijk items herhalen. Bijvoorbeeld:

- Nieuws
-- Product 1
- Producten
-- Product 1
- etc.

Met onderstaande functie lees ik de hoofdcategorien en alle submenu's uit:

code:
1
2
3
4
5
6
7
8
9
10
11
12
<?php 
function toon_menu($m_id, $m_parentid) { 
$result = mysql_query('SELECT m_categorie FROM menu WHERE m_parentid="'.$m_parentid.'''); 
while ($row = mysql_fetch_array($result)) 
{ 
    echo str_repeat('  ',$m_parentid).$row['m_categorie']."<br>\n"; 
    toon_menu($row['m_categorie'], $m_parentid+1); 
   } 
} 

toon_menu(0,0); 
?>


Ter illustratie hoe een gevulde tabel er ongeveer uit ziet:

m_id | m_categorie | m_parentid
1 Nieuws 0
2 Producten 0
3 Nieuwsitems 1
4 Product 1 2
5 Product 2 2

m_id is een int en wordt automatisch verhoogd
m_categorie is de naam van de hoofdcategorie of subcategorie
m_partentid is het id van de parent, 0 is de hoofdcategorie.

De bedoeling is iig dat het menu oneindig diep kan worden en dat ik als beheerder gemakkelijk levels met bijbehorende pagina's kan toevoegen en verwijderen. Ik denk er bijna te zijn maar mis waarschijnlijk iets kleins.

Acties:
  • 0 Henk 'm!

  • Scott
  • Registratie: December 2004
  • Laatst online: 20-09 21:57

Scott

Ik ben, dus ik tweak

Ik zie nergens waar je het eerste argument gebruikt ($m_id). Is dat omdat dit ergens anders in de code staat of heb je hier iets over het hoofd gezien ?

Verder zou ik dit eens proberen in je while:

PHP:
1
toon_menu($row['m_categorie'], $row['m_id']); // Uiteraard ook even in je query opnemen ;)

[ Voor 9% gewijzigd door Scott op 21-08-2007 01:58 ]


Acties:
  • 0 Henk 'm!

  • Crayne
  • Registratie: Januari 2002
  • Laatst online: 17-03 13:41

Crayne

Have face, will travel

Je maakt een denkfout in je code. Je wilt niet één optellen bij je doorgegeven argument bij het recursief aanroepen van je functie. Je wilt per hoofditem dat je oproept alle items oproepen dat als hun m_parentid het huidige m_id hebben.

Dit is jouw code (en je ziet dat de parser er weinig van kan maken):

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
<?php 
function toon_menu($m_id, $m_parentid) { 
$result = mysql_query('SELECT m_categorie FROM menu WHERE m_parentid="'.$m_parentid.'''); 
while ($row = mysql_fetch_array($result)) 
{ 
echo str_repeat(' ',$m_parentid).$row['m_categorie']."<br>\n"; 
toon_menu($row['m_categorie'], $m_parentid+1); 
} 
} 

toon_menu(0,0); 
?>


En dit is wat je zoekt.

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?php 

function toon_menu($m_parentid) { 

    $query = sprintf('SELECT m_id, m_categorie FROM menu WHERE m_parentid=%d', $m_parentid);
    $result = mysql_query($query); 

    while ($row = mysql_fetch_array($result)) 
    {
     
        echo str_repeat('  ', $m_parentid).$row['m_categorie']."<br>\n";
        toon_menu($row['m_id']);

    } 

} 

toon_menu(0); 

?>


Tenminste, dat is wat ik begrijp uit je verhaal.

Mijn Library Thing catalogus


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Beide heren bedankt voor de hulp.

Het werkt inmiddels door de code van Crayne te pasten (wat een luxe :) ). Ik heb het nog niet heel uitgebreid kunnen testen omdat ik de database nog even met testmateriaal moet vullen maar het ziet er goed uit en de uitleg is helder. Je hebt mijn denkfout er in ieder geval gemakkelijk uitgefiltert.

Ik snap alleen niet helemaal wat je hier precies doet: WHERE m_parentid=%d', $m_parentid
Wat is %d? Ik heb het geprobeerd te Googlen maar dat resulteert in een jungle van nutteloze antwoorden.

Acties:
  • 0 Henk 'm!

  • FragFrog
  • Registratie: September 2001
  • Laatst online: 22:47
Crayne maakt gebruik van in mijn opinie een van de mooiste manieren om je query (inline) op te bouwen, namelijk met behulp van sprintf().

%d geeft in dit geval aan dat het argument als integer behandelt moet worden:
d - the argument is treated as an integer, and presented as a (signed) decimal number.
Het is in feite een workaround voor PHP's weaktyped variabelen die ervoor zorgt dat je eigenlijk je parentID verder niet meer hoeft te controleren omdat het toch altijd een integer oplevert zodat je nooit last zal hebben van SQL injecties. Werkt uiteraard niet met %s, strings, maar voor weergeven en werken met getallen zeker de moeite van het in verdiepen waard :)

[ Site ] [ twitch ] [ jijbuis ]


Acties:
  • 0 Henk 'm!

  • r0bert
  • Registratie: September 2001
  • Laatst online: 30-07 02:32
Niet zozeer over de code, maar meer over je opzet zelf. Als je echt een beheersbaar menu wilt hebben zul je de parent bij moeten houden, maar ook de positie (in volgorde). Een SORT BY op een zelfgemaakte index (bijvoorbeeld integer of varchar) zal erg serverintensief worden, bijvoorbeeld bij verplaatsen van items. Het beste kun je één of beide buren onthouden. Zo weet je altijd de exacte positie.
Pagina: 1