Recursief menuscript uitbreiden

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Business Intelligence ontwikkelaar (Microsoft tool

Bedrijfsomschrijving De organisatie is ruim 80 man groot en is aanbieder van een zeer groot en divers aanbod van consumentenproducten in Nederland. Oorspronkelijk is het een familiebedrijf die is opgericht in 2001. De IT afdeling is ruim 15 man groot. Binnen de organisatie heerst een erg open en informele werksfeer. Functieomschrijving Door toenemende vraag vanuit de business naar management informatie is de organisatie momenteel opzoek ter uitbreiding naar een ervaren Microsoft Business Intelligence ontwikkelaar. In deze functie ben je nauw betrokken binnen het gehele BI traject; van informatie analyse, datawarehouse ontwikkeling/beheer tot de bouw van rapportages. Het betreft een zeer

Bekijk vacature »

Drupal Developer / Kritische applicaties @ Utrecht

2021-06-21 iSense Drupal Developer Kritische applicaties Wil jij werken voor een organisatie die werkt met de nieuwste technieken op het gebied van software ontwikkeling, een groot maatschappelijk belang heeft en een zeer diverse omgeving? Lees dan snel verder! ISB42382 Organisatie Je gaat werken bij een groot onderzoeksinstituut in de omgeving Zeist die een rijke historie heeft en al meer dan 100 jaar bestaat. Als Drupal Developer ga jij deelnemen aan een groot aantal websites en zal je software bouwen voor verschillende branches met een groot maatschappelijk belang. Deze organisatie is verantwoordelijk voor allerlei onderzoeken en hebben dan ook een groot

Bekijk vacature »

HR Organization Developer NL/DE

Als Organization Developer help je mee Coolblue zo in te richten dat alle Coolblue’ers optimaal hun werk kunnen doen. Wat doe je als HR Organization Developer NL/DE bij Coolblue? Heb jij een passie voor HR en doorvoeren van verbeteringen en wil je deze tastbaar maken door te werken aan interessante projecten, onder andere het uitbreiden van CoolblueBezorgt in Duitsland? Dan is dit dé functie voor jou. Ook HR Organization Developer worden bij Coolblue? Lees hieronder of het bij je past. Dit vind je leuk om te doen Zorgen voor het juiste organisatiemodel op jouw afdelingen, voor vandaag en voor de

Bekijk vacature »

Junior Software Developers gezocht!

Bedrijfsomschrijving Onze opdrachtgever is een bekende internationale speler binnen de branche waarin ze werken. Ze hebben vestigingen door heel Nederland maar de R&D afdeling is gelegen in het zuiden van Overijssel. Deze organisatie is voor hun klanten continu bezig om oplossingen te bedenken die bijdragen aan een duurzame leefomgeving. Om het IT team te versterken zijn ze op zoek naar een Junior Developer. Binnen het team zal je werken aan interne software oplossingen die gebruikt zullen worden door de gehele organisatie (in binnen- en buitenland). Functieomschrijving Je gaat hier werken met technieken als C#, ASP.Net en Javascript, hiermee ga je

Bekijk vacature »

Java Developer @ Utrecht

2021-06-08 iSense Java Developer Do you like DevOps way of working? Are you looking for an exciting opportunity where latest and greatest technologies are applied? Would you like to take responsibility in each and every step of software development lifecycle ? ISKE50115 Organization You will work at global financial organization with a head office in the Netherlands. You will be part of one of the most important departments in the core banking domain. The organization has a very strong commitment to the collaboration and communication culture among different development teams. You are going to work in a squad that is

Bekijk vacature »

PHP Developer / Microservices @ Utrecht

2021-08-12 iSense PHP Developer / Microservices Ben jij een PHP/Web Developer met minimaal 2-3 jaar ervaring en wil je meewerken aan het ombouwen van een grote monoliet naar een compleet nieuw Microservices platform? Lijkt het je leuk om te werken bij een hechte organisatie die inmiddels een grote en bekende speler is geworden op HR gebied binnen Nederland? Lees dan nu verder! ISP50438 Organisatie Als PHP/Web Developer ga je aan de slag bij een organisatie die de afgelopen jaren gegroeid is naar een bekende speler op HR gebied binnen Nederland. Hun platform zorgt er voor dat vraag en aanbod van

Bekijk vacature »

Junior PHP Developer

Je maakt een vliegende start van je carrière, door meteen mee te bouwen aan de digitale aspecten van Coolblue. De eerst volgende selectiedag staat gepland op 29 juli! Wat doe je als Junior PHP Developer bij Coolblue? Als Junior PHP Developer ben je meteen vanaf de start onderdeel van een development team. Je kijkt veel mee met collega’s en volgt trainingen om te groeien als Junior Developer. Op dat moment komt je wil om steeds te blijven leren naar boven. Daarnaast pak je in de sprints ook je eigen stories op om Coolblue iedere dag een beetje beter te kunnen

Bekijk vacature »

Senior Backend developer - Automotive

We are looking for a highly motivated and experienced Backend developer. Required Qualifications: ● 6+ years experience with a server-side programming technology ● Experience with SQL Databases ● Experience with Go(lang) ● Experience with GCP ● Hands-on test-driven development (TDD), data analytics, and SQL experience ● Experience in producing REST and RPC based services ● Experience building secure and highly-available distributed systems/microservices ● Experience with Git-based versioning and Git workflows ● Knowledge of Redis, Docker, Setting up CI/CD pipelines and Unix command line ● Knowledge of Jira and Scrum techniques ● Excellent communication skills ● Must be a self-starter with

Bekijk vacature »

Fullstack Developer /.NET Core @ Almere

2021-08-16 iSense Fullstack Developer /.NET Core Ben jij een ervaren Fullstack Developer, die graag zijn expertise van NET.Core inzet in een dynamische en bedrijf kritische omgeving? Is een jonge club waar je als IT-team het hart vormt van de organisatie, echt iets voor jou? Lees dan snel verder! ISMA49157 Organisatie Als Fullstack Developer kom je te werken in de regio Almere bij een organisatie, dat als internationale marktleider opereert op het gebied van detailhandel. Vanuit ruim tienduizend locaties verkopen zij hun producten aan de klanten. Om diverse data en bedrijfsprocessen van HR, CRM tot inkoop overzichtelijk in beeld te hebben

Bekijk vacature »

PHP Developer Javascript / Agile

Wie wordt jouw werkgever?: Wij hebben veel ervaring in het ontwikkelen van websites en applicaties. Wil jij werken als PHP developer? Heb jij ervaring met PHP? Vaste baan: PHP Developer Javascript Agile 3.000 - 4.300 PHP Developer Een webbureau met veel ervaring in het ontwikkelen van websites en applicaties. We blijven up-to-date met nieuwe (technische) mogelijkheden van het internet, om de klant optimaal te kunnen adviseren. We zijn een dynamische organisatie met veel kennis van het internet. Op kantoor is een ontspannen maar professionele werksfeer waar veel ruimte is om je verder te ontwikkelen. Wij werken voor MKB klanten. We

Bekijk vacature »

Full Stack Java Developer Graduate Program - Exper

Via Experis Academy krijg je een unieke kans om de in de branche gewilde expertise op te doen die jou tot een gewilde Full Stack Java Developer met een frontend-specialisatie maken. Het programma duurt 21 maanden en eindigt met een vaste baan bij een van onze vele, boeiende klanten, of je blijft bij ons (Experis) werken. Ons programma tot Java Developer Experis Academy start met een op maat gemaakte cursus die drie maanden duurt. Gedurende deze maanden komen theorie, praktijk en Java-certificeringen aan bod. Hierbij is het onderwijsprogramma gebaseerd op de principes als versnelde training en flipped classroom. De volgende

Bekijk vacature »

Mendix Ontwikkelaar Logistiek Bedrijf / HBO

Voor wie je gaat werken: Wij zijn een bergingsbedrijf. Wil jij graag aan de slag als Mendix Ontwikkelaar? Heb jij al ervaring met Mendix? Vaste baan: Mendix Ontwikkelaar Logistiek Bedrijf HBO 2.800 - 4.200 Mendix Ontwikkelaar Wij garanderen op elk moment mobiliteit. Een flinke belofte, waarvoor we graag alles uit de kast halen. Van het bergen en transporteren tot het zorgen voor vervangend vervoer, in heel Europa. En dat doen we echt samen! Met onze chauffeurs op de weg, onze planners van de transportplanning, onze helden in de meldkamers en onze toppers van IT, financiën en HRM; allemaal mensen waar

Bekijk vacature »

.Net Developer IoT / Software

Voor wie je gaat werken: Wij zijn gespecialiseerd in het op afstand bewaken en besturen van machines en processen. Ben jij een ervaren .Net developer? Heb jij ervaring met het verbeteren en implementeren van .NET applicaties? Vaste baan: .Net Developer IoT Software 3.000 - 4.200 .Net Developer Wij zijn een snel groeiende onderneming gespecialiseerd in het op afstand bewaken en besturen van machines en processen, IoT (Internet of Things). Wij zijn een veelzijdige organisatie. Je werkt voor onze eigen IT organisatie. We werken met moderne technologie en staan open voor innovatie. Wil jij bij de top specialisten horen? Ben jij

Bekijk vacature »

Outsystems Developer @ Amsterdam

2021-08-26 iSense Outsystems Developer Ben je een Outsystemsdeveloper en houd je van ownership? Lijkt het je interessant om een team met developers samen te stellen en mooie applicaties te bouwen voor nationale en internationale klanten? Wil je werken in een organisatie die aan de vooravond staat van mooie ontwikkelingen? Dan is dit de functie voor jou! Reageer snel! ISNO50007 Organisatie Deze financiële instelling is gevestigd in hartje Amsterdam. Ze hebben als doel hun klanten op een effectieve en onafhankelijke manier te begeleiden bij belangrijke vermogensgerelateerde beslissingen. Privacy staat hoog in het vaandel, aangezien zij een maatschappelijke rol vervullen die nooit

Bekijk vacature »

Fullstack .NET DEVELOPER - GRADUATE PROGRAM @ Rand

2021-06-10 iSense Fullstack .NET DEVELOPER - GRADUATE PROGRAM Ben je onlangs afgestudeerd van een IT-opleiding of heb je nog maar weinig ervaring opgedaan? En wil je toch graag aan de slag als .NET Developer? Lees dan snel verder, want op 9 augustus 2021 starten wij weer met een graduate programma waarin jij jezelf kunt ontwikkelen tot een volwaardige Fullstack .NET Developer! ISLE50166 Locatie Randstad/Eindhoven Wat ga je doen tijdens het Fullstack .NET Developer Graduate Programma? In augustus krijg jij via de Experis Academy een unieke kans om jouw IT-carrière een kickstart te geven en jezelf te ontwikkelen tot Fullstack .NET

Bekijk vacature »
Snelle Jaap

Snelle Jaap

27/06/2019 13:35:53
Quote Anchor link
Ik heb een recursief menu script dat oneindig niveau's diep kan gaan aan de hand van parents en subs maar nu loop ik tegen een probleem aan.

Dit is de situatie:

Momenteel is het menu opgebouwd uit categorieën, dat houd in, hoofdcategorieen en subcategorieen, je kan die oneindig door linken onder elkaar. Dat werkt prima maar nu heb ik in mijn CMS ook `artikelen` dit zijn pagina's die alleen maar onder categorieën kunnen hangen en dus niet oneindig diep, deze gaan maar 1 niveau diep, altijd onder een categorie.

parent_id is het id waarmee een categorie aan een andere categorie is gekoppeld
catid is het id waarmee een artikel aan een categorie is gekoppeld

Het lukt mij niet dit artikelen te tonen in mijn menu.

Momenteel is dit de hoofdquery die alle categorieen ophaalt:

SELECT cat.id as cat_id, cat.level, cat.parent_id, cat.title as cat_title, cat.alias as cat_alias, cat.published, cat.rgt, cnt.state, cnt.id as content_id, cnt.catid, cnt.title as content_title, cnt.alias as content_alias
FROM snm_categories cat
LEFT JOIN snm_content cnt
ON cnt.catid = cat.id
WHERE cat.id NOT IN (1, 2, 3, 4, 5, 7, 8)
AND cat.published = 1
GROUP BY cat.id
ORDER BY cat.rgt ASC

Op de volgende manier stop ik dan alles in een menu:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
<div id="main-menu" class="main-nav zn_mega_wrapper ">
  <ul id="menu-main-menu" class="main-menu zn_mega_menu">
    <li><a href="home">Home</a></li>
    <?PHP
    $alias
= $_GET['alias'];
    //Haal alle categorieen en check gelijk of de desbetreffende categorie artikelen onder zich heeft hangen.
    $menu = "
    SELECT cat.id as cat_id, cat.level, cat.parent_id, cat.title as cat_title, cat.alias as cat_alias, cat.published, cat.rgt, cnt.state, cnt.id as content_id, cnt.catid, cnt.title as content_title, cnt.alias as content_alias
    FROM snm_categories cat
    LEFT JOIN snm_content cnt
    ON cnt.catid = cat.id
    WHERE cat.id NOT IN (1, 2, 3, 4, 5, 7, 8)
    AND cat.published = 1
    GROUP BY cat.id
    ORDER BY cat.rgt ASC"
;
    $menuconn = $conn->query($menu);
    // Maak een nieuwe array om te vullen met onderstaand resultaat
    $menuData = array(
        'items' => array(),
        'parents' => array()
    );

    // Maak een nieuwe array met simpelweg items en parents, welke gekoppeld zitten aan cat_id/parent_id
    while($menu = $menuconn->fetch_assoc())
    {

        $menuData['items'][$menu['cat_id']] = $menu;
        $menuData['parents'][$menu['parent_id']][] = $menu['cat_id'];
    }


    // Functie om menu te maken, $parentId is 1 (de categorieen die geen parent hebben)
    function buildMenu($parentId, $menuData)
    {

        $html = '';
        if (isset($menuData['parents'][$parentId]))
        {

            //Als parent_id gelijk is aan 1 gooi een li eromheen (want het is geen subcat) anders een ul
            if($parentId == '1'){
              $html = '<li>';
            }
else{
              $html = '<ul class="sub-menu">';
            }

            foreach ($menuData['parents'][$parentId] as $itemId)
            {

                $html .= '<li class="menu-item"><a href="info/'.$menuData['items'][$itemId]['cat_alias'].'">'.$menuData['items'][$itemId]['cat_title'].'</a>';

                // Voer deze functie uit binnen de functie loop (recursief)
                $html .= buildMenu($itemId, $menuData);

                $html .= '</li>';
            }

            //Als parent_id gelijk is aan 1 gooi een li eromheen (want het is geen subcat)
            if($parentId == '1'){
              $html .= '</li>';
            }
else{
              $html .= '</ul>';
            }
        }

        return $html;
    }

    // Echo het resultaat van de functie en geef 1 mee als parent_id
    echo buildMenu(1, $menuData);
    ?>

  </ul>
</div>


Nu probeer ik de artikelen op deze manier erbij te plaatsen:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
<div id="main-menu" class="main-nav zn_mega_wrapper ">
  <ul id="menu-main-menu" class="main-menu zn_mega_menu">
    <li><a href="home">Home</a></li>
    <?PHP
    $alias
= $_GET['alias'];
    //Haal alle categorieen en check gelijk of de desbetreffende categorie artikelen onder zich heeft hangen.
    $menu = "
    SELECT cat.id as cat_id, cat.level, cat.parent_id, cat.title as cat_title, cat.alias as cat_alias, cat.published, cat.rgt, cnt.state, cnt.id as content_id, cnt.catid, cnt.title as content_title, cnt.alias as content_alias
    FROM snm_categories cat
    LEFT JOIN snm_content cnt
    ON cnt.catid = cat.id
    WHERE cat.id NOT IN (1, 2, 3, 4, 5, 7, 8)
    AND cat.published = 1
    GROUP BY cat.id
    ORDER BY cat.rgt ASC"
;
    $menuconn = $conn->query($menu);
    // Maak een nieuwe array om te vullen met onderstaand resultaat
    $menuData = array(
        'items' => array(),
        'parents' => array()
    );

    // Maak een nieuwe array met simpelweg items en parents, welke gekoppeld zitten aan cat_id/parent_id
    while($menu = $menuconn->fetch_assoc())
    {

        $menuData['items'][$menu['cat_id']] = $menu;
        $menuData['parents'][$menu['parent_id']][] = $menu['cat_id'];

        // Hier haal ik de artikelen onder de juiste categorie
        $submenu = "SELECT * FROM snm_content WHERE catid = '".$conn->real_escape_string($menu['cat_id'])."' AND catid NOT IN (8) AND state = 1 ORDER BY ordering";
        $submenuconn = $conn->query($submenu);
        while($submenu = $submenuconn->fetch_assoc()){
          $artikelsubs = '<li class="menu-item"><a href="info/'.$submenu['alias'].'">'.$submenu['title'].'</a>';
        }
    }


    // Functie om menu te maken, $parentId is 1 (de categorieen die geen parent hebben)
    function buildMenu($parentId, $menuData)
    {

        $html = '';
        if (isset($menuData['parents'][$parentId]))
        {

            //Als parent_id gelijk is aan 1 gooi een li eromheen (want het is geen subcat) anders een ul
            if($parentId == '1'){
              $html = '<li>';
            }
else{
              $html = '<ul class="sub-menu">';
            }

            foreach ($menuData['parents'][$parentId] as $itemId)
            {

                $html .= '<li class="menu-item"><a href="info/'.$menuData['items'][$itemId]['cat_alias'].'">'.$menuData['items'][$itemId]['cat_title'].'</a>';
                // Voer deze functie uit binnen de functie loop (recursief)
                $html .= buildMenu($itemId, $menuData);

                $html .= '</li>';

            }

            //Als parent_id gelijk is aan 1 gooi een li eromheen (want het is geen subcat)
            if($parentId == '1'){
              $html .= '</li>';
              $html .= $artikelsubs;
            }
else{
              $html .= '</ul>';
            }
        }

        return $html;
    }

    // Echo het resultaat van de functie en geef 1 mee als parent_id
    echo buildMenu(1, $menuData);
    ?>

  </ul>
</div>
Maar helaas zie ik niks in de broncode staan of op de website qua artikelen. Weet iemand waar het misgaat?

Als ik de query in phpmyadmin test met bijvoorbeeld '9' op de plaats van '".$conn->real_escape_string($menu['cat_id'])."' dan krijg ik de juiste data te zien.
 
PHP hulp

PHP hulp

21/09/2021 02:06:07
 
Thomas van den Heuvel

Thomas van den Heuvel

27/06/2019 14:10:14
Quote Anchor link
Quote:
Als ik de query in phpmyadmin test met bijvoorbeeld '9' op de plaats van '".$conn->real_escape_string($menu['cat_id'])."' dan krijg ik de juiste data te zien.

Dit laatste vertelt je alleen dat de oorspronkelijke data die je ophaalt goed / volledig is.

Vervolgens stop je dit in een datastructuur.

En deze datastructuur voer je aan een functie.

Dit zijn dus meerdere stappen.

Controleer de datastructuur $menuData, bijvoorbeeld door deze naar het scherm te dumpen.

Deze regel:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
<?php
$menuData
['parents'][$menu['parent_id']][] = $menu['cat_id'];
?>

Is wellicht correct, maar dat zijn geen parents, maar children. Je voegt namelijk het huidige item toe als child van de parent :). En waarom zou je dat uberhaupt compliceren met twee subarrays? Nu kopieer je gewoon de "rauwe" kolomnamen van een recordrij ($menu) naar een array, maar je zou ook nettere/beter leesbare kolommen kunnen definiëren.

De naam $menuconn is ook misleidend. Dit is een result-object, geen connectie-object.

En dan de constructie van regel 23 t/m 34. Een query in een while-loop is vrijwel altijd een "code smell".

Ook het if-statement van regel 40 is niet nodig:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
if (isset($menuData['parents'][$parentId])) { ... }

Je roept namelijk buildMenu() aan in een loop waarin je precies deze items doorloopt, die hoef je dan na aanroep niet nogmaals te controleren...

Als je $menuData nu eens wat zinniger had gestructureerd, bijvoorbeeld door de keys van dit array simpelweg het categorie-id te laten zijn, dan had je met een array_keys() de keys van het array hierop direct (met één query) alle relevante artikelen op kunnen halen.

En als je van dit alles een class had gemaakt, dan hoef je ook niet elke functie-aanroep het hele array mee te geven, de datastructuur kun je opslaan als klasse-variabele.

Ik heb een deja vu. Ik weet vrij zeker dat ik je (mogelijk in een ver verleden) als eens heb voorgesteld om het bouwen van de datastructuur en het weergeven van deze structuur in een HTML-menu beter in afzondering kan doen. Sterker nog, de hele bovenstaande aanpak passeerde daarin volgens mij de revue.

Ik zou dus die datastructuur ($menuData) eens onder de loep nemen en herstructureren zodat je hier handiger gebruik van kunt maken.

Functie om een en ander in leesbare vorm te dumpen:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php
// escape functie
function escape($in) {
    return htmlspecialchars($in, ENT_QUOTES, 'UTF-8'); // aangenomen dat je UTF-8 gebruikt
}

// veilige dump functie (alles wordt weergegeven als tekst en wordt niet geinterpreteerd als HTML/JS)
function dump($in) {
    if (is_array($in)) {
        $in = print_r($in, true);
    }

    echo '<pre>'.escape($in).'</pre>';
}

?>
Gewijzigd op 28/06/2019 12:43:56 door Thomas van den Heuvel
 
Snelle Jaap

Snelle Jaap

02/07/2019 13:47:51
Quote Anchor link
@Tomas van heuvel,

Klopt ik heb al een keer eerder iets gevraagd over dit script. Bedankt voor de uitleg ik ga proberen er iets mee te doen.
 



Overzicht Reageren

 
 

Om de gebruiksvriendelijkheid van onze website en diensten te optimaliseren maken wij gebruik van cookies. Deze cookies gebruiken wij voor functionaliteiten, analytische gegevens en marketing doeleinden. U vindt meer informatie in onze privacy statement.