[php] Array omzetten naar menu met children

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Dimby
  • Registratie: April 2008
  • Laatst online: 01-07-2024
Hallo mede-tweakers,

Nadat ik gisteren een hele tijd heb staan te kl*ten met dit systeem vraag ik toch om jullie hulp.
Wat ik wil is vrij simpel, ik ben voor mezelf een simpel CMS systeem aan het maken en wil pagina's onderliggend ( childrens ) aan elkaar kunnen maken.

Een voorbeeld van een menu volgorde:
code:
1
2
3
4
5
6
7
8
Pagina 1
 - Pagina 3
    - Pagina 4
       - Pagina 6
          - Pagina 7
          - Pagina 8
 - Pagina 5
Pagina 2


Om dit te bereiken heb ik iedere pagina in de database een parent waarde gegeven.
In dit voorbeeld heeft pagina 3 als parent 1 en pagina 4 als parent 3 etc.
Pagina's zonder een bovenliggende pagina heb ik als parent waarde 0 gegeven.

Nu komt het probleem, deze pagina's wil ik vanuit de database netjes in een menu zetten ( met 1 database request ). Zelf heb ik, in mijn ogen, een heel omslaschtige manier verzonnen.

Ok, niet lachen :+

Nadat ik alle pagina's uit de database heb gehaald stop ik ze in een nieuwe array waarbij de key de parent is, oftewel ik sorteer ze op hun parent. Vervolgens ga ik met een foreach loop iedere parent af en controleer of er kinderen zijn. Deze manier is volgens mij heel omslachtig en moet er een andere simpelere methode zijn. Het liefst wil ik onbeperkt pagina's onder elkaar kunnen plaatsen.

PHP:
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
75
76
77
78
79
80
81
<?php
$pages = array(
    array('name' => 'Pagina 1','id' => 1,'parent' => 0),
    array('name' => 'Pagina 2','id' => 2,'parent' => 0),
    array('name' => 'Pagina 3','id' => 3,'parent' => 1),
    array('name' => 'Pagina 4','id' => 4,'parent' => 3),
    array('name' => 'Pagina 5','id' => 5,'parent' => 1),
    array('name' => 'Pagina 6','id' => 6,'parent' => 4),
    array('name' => 'Pagina 7','id' => 7,'parent' => 6),
    array('name' => 'Pagina 8','id' => 8,'parent' => 6),
);

$num_parents = 0;
$encountered_parents = array();

foreach($pages as $page)
{
    $list_parents[$page['parent']][] = $page;
    
    if( !array_key_exists( $page['parent'], $encountered_parents ) )
    {
        $num_parents++;
        $encountered_parents[ $page['parent'] ] = true;
    }
}

echo '<pre>'; print_r($list_parents); echo '</pre>';

echo '<ul>';
foreach( $list_parents[0] as $page )
{
    echo '<li>';
    echo $page['name'];
    if( array_key_exists($page['id'], $list_parents) )
    {
        echo '<ul>';    
            foreach( $list_parents[ $page['id'] ] as $layer2 )
            {   
            echo '<li>';
            echo $layer2['name'];
                if( array_key_exists($layer2['id'], $list_parents) )
                {
                    echo '<ul>';
                        foreach( $list_parents[ $layer2['id'] ] as $layer3 )
                        {
                        echo '<li>';
                        echo $layer3['name'];
                            if( array_key_exists($layer3['id'], $list_parents) )
                            {
                                echo '<ul>';
                                    foreach( $list_parents[ $layer3['id'] ] as $layer4 )
                                    {
                                    echo '<li>';
                                    echo $layer4['name'];
                                    if( array_key_exists($layer4['id'], $list_parents) )
                                    {
                                        echo '<ul>';
                                            foreach( $list_parents[ $layer4['id'] ] as $layer5 )
                                            {
                                            echo '<li>';
                                            echo $layer5['name'];
                                            echo '</li>';
                                            }   
                                        echo '</ul>';
                                    }
                                    echo '</li>';
                                    }   
                                echo '</ul>';   
                            }
                        echo '</li>';
                        }   
                    echo '</ul>';
                }
            echo '</li>';
            }
        echo '</ul>';
    }
    echo '</li>';
}
echo '</ul>';
?>


De $list_parents heeft de volgende structuur:

PHP:
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
75
76
77
78
79
Array
(
    [0] => Array
        (
            [0] => Array
                (
                    [name] => Pagina 1
                    [id] => 1
                    [parent] => 0
                )

            [1] => Array
                (
                    [name] => Pagina 2
                    [id] => 2
                    [parent] => 0
                )

        )

    [1] => Array
        (
            [0] => Array
                (
                    [name] => Pagina 3
                    [id] => 3
                    [parent] => 1
                )

            [1] => Array
                (
                    [name] => Pagina 5
                    [id] => 5
                    [parent] => 1
                )

        )

    [3] => Array
        (
            [0] => Array
                (
                    [name] => Pagina 4
                    [id] => 4
                    [parent] => 3
                )

        )

    [4] => Array
        (
            [0] => Array
                (
                    [name] => Pagina 6
                    [id] => 6
                    [parent] => 4
                )

        )

    [6] => Array
        (
            [0] => Array
                (
                    [name] => Pagina 7
                    [id] => 7
                    [parent] => 6
                )

            [1] => Array
                (
                    [name] => Pagina 5
                    [id] => 8
                    [parent] => 6
                )

        )

)

Acties:
  • 0 Henk 'm!

  • mithras
  • Registratie: Maart 2003
  • Niet online
Mm, ja dat is niet bijzonder efficient inderdaad ;)

Je hebt twee opties: bekijk de blog van crisp of lees iets over nested sets. Er zijn adhv deze termen genoeg code-voorbeelden te vinden die je kan gerbuiken.

Acties:
  • 0 Henk 'm!

  • Voutloos
  • Registratie: Januari 2002
  • Niet online
Een (recursieve) functie had je in in ieder geval 80% van het typewerk (copy paste werk ;) ) bespaard, maar wellicht wil je eerst wat lezen want probleem is al vaker langsgekomen.

[ Voor 27% gewijzigd door Voutloos op 22-06-2010 09:15 ]

{signature}


Acties:
  • 0 Henk 'm!

  • TJHeuvel
  • Registratie: Mei 2008
  • Niet online
Misschien is recursion iets voor jou?

Wat je wilt doen is 1 functie maken welke je $list_parents als argument geeft, en die maakt de UL en LI. Hij roept ook zichzelf aan als de node nog child-elements heeft, zodat het menu recursief word opgebouwd.

Zo kan je een oneindig diep menu maken, maar pas wel op: infinite loops zijn zo gemaakt!

Freelance Unity3D developer


Acties:
  • 0 Henk 'm!

  • MueR
  • Registratie: Januari 2004
  • Laatst online: 14:53

MueR

Admin Tweakers Discord

is niet lief

Ik wil niet in herhaling vallen, maar je zoek recursion :+

Anyone who gets in between me and my morning coffee should be insecure.


Acties:
  • 0 Henk 'm!

  • Dimby
  • Registratie: April 2008
  • Laatst online: 01-07-2024
Bedankt voor jullie reacties!
Met behulp van recursie en de blog van crisp en heb een oplossing gevonden.

Hier de code zodat de mensen na mij er ook nog profijt van hebben :)

PHP:
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
<?php

$pages = array(
    array('name' => 'Pagina 1','id' => 1,'parent' => 0),
    array('name' => 'Pagina 2','id' => 2,'parent' => 0),
    array('name' => 'Pagina 3','id' => 3,'parent' => 1),
    array('name' => 'Pagina 4','id' => 4,'parent' => 3),
    array('name' => 'Pagina 5','id' => 5,'parent' => 1),
    array('name' => 'Pagina 6','id' => 6,'parent' => 4),
    array('name' => 'Pagina 7','id' => 7,'parent' => 6),
    array('name' => 'Pagina 5','id' => 8,'parent' => 6),
);

//Replace with database fetching ;)
foreach( $pages as $page )
{ 
    $menu_data['items'][$page['id']] = $page; 
    $menu_data['parents'][$page['parent']][] = $page['id']; 
} 

function build_menu( $parent_id = 0, $menu_data = array() ) 
{ 
    if( isSet($menu_data['parents'][$parent_id]) ) 
    { 
        $html = '<ul>'; 
        
            foreach( $menu_data['parents'][$parent_id] as $item_id ) 
                $html .= '<li>' . $menu_data['items'][$item_id]['name'] . build_menu($item_id, $menu_data) . '</li>'; 
            
        $html .= '</ul>'; 
    } 

    return isSet($html) ? $html : false ; 
} 

echo build_menu(0, $menu_data); 

?>

[ Voor 5% gewijzigd door Dimby op 22-06-2010 10:33 ]


Acties:
  • 0 Henk 'm!

  • MueR
  • Registratie: Januari 2004
  • Laatst online: 14:53

MueR

Admin Tweakers Discord

is niet lief

d:)b Zo zien we het graag!

Anyone who gets in between me and my morning coffee should be insecure.


Acties:
  • 0 Henk 'm!

  • Mischa_NL
  • Registratie: Mei 2004
  • Laatst online: 01-02-2023
Het kan uiteraard ook iteratief met een stack/queue waar je children instopt en doorheen loopt. Maar net wat je graag wilt.

Acties:
  • 0 Henk 'm!

  • Maaark
  • Registratie: Juli 2008
  • Laatst online: 19-09 19:33
Thanks, dit zocht ik net :)
Pagina: 1