[php] recursive arrays probleem

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Justice
  • Registratie: Maart 2001
  • Laatst online: 07-08 15:02
Ik ben bezig om een menu te genereren aan de hand van bestandsnamen van de bestanden in een directory. Om de structuur te genereren (main menu en submenu) gebruik ik recursive arrays omdat de naam dus variabel is.

Echter ik krijg de error (inclusief de m):
m

Warning: Invalid argument supplied for foreach() in W:\www\WebInclude\debug2.php on line 18
De code is een lichte aangepaste versie uit [rml][ PHP] variabele variabelen[/rml] als testcase. Echter ik snap niet waar de error vandaan komt en waarom er 1 letter geprint wordt.
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
<?php
$items = array ( 
    'name'      => 'menu', 
    'children'  => array (
        array (
            'name'      => 'about', 
            'children'  => array ( 'us', 'this-site' ) 
        ), 
        array (
            'name' => 'links',
            'children' => array ( 'external', 'internal') 
        ) 
    ) 
);

function print_items ( $items ) { 
    echo '<ul>'; 
    foreach ($items as $item) { 
        echo $item [ 'name' ]; 
        if ( count ( $item [ 'children' ] ) > 0 ) { 
           print_items ( $item [ 'children' ] ); 
        } 
    } 
    echo '</ul>'; 
} 

print_items ( $items );
?>

De html klopt nog niet ;)

[ Voor 33% gewijzigd door Justice op 05-02-2004 00:28 ]

Human Bobby


Acties:
  • 0 Henk 'm!

  • Macros
  • Registratie: Februari 2000
  • Laatst online: 15-05 16:29

Macros

I'm watching...

Ik heb je script een klein beetje herschreven. Ik weet ook niet precies wat er mis ging, maar zo is het makkelijker:
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
<?php
$items = array (
    'name'         => 'menu',
    'children'    => array (
        array (
            'name'        => 'about',
            'children'  => array ( 'us', 'this-site' )
          ),
          array (
            'name' => 'links',
            'children' => array ( 'external', 'internal')
        )
    )
);

function print_items ( $items , $dep) {
    if (is_array($items)){
        echo str_repeat(' ',$dep)."<ul>\n";
        foreach ($items as $item) {
            print_items($item, $dep+1);
        }
        echo str_repeat(' ',$dep)."</ul>\n";
    } else {
        echo str_repeat(' ',$dep).$items . "\n";
    }
}
//print_r($items);

print_items ( $items , $dep );
?>

Deze oplossing maakt geen gebruik van de naam van een veld, maar dat kan je veranderen door de foreach te veranderen naar foreach($items as $key => $item)
dan kan je op de key checken en wat anders doen dan recursief printen maar een andere print functie aanroepen ofzo.

[ Voor 45% gewijzigd door Macros op 05-02-2004 00:42 . Reden: Wat meer commentaar erbij gezet. ]

"Beauty is the ultimate defence against complexity." David Gelernter


Acties:
  • 0 Henk 'm!

  • X-Lars
  • Registratie: Januari 2004
  • Niet online

X-Lars

Just GoT it.

check this, geeft al een beter beeld van wat er mis gaat:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?php 
error_reporting(E_ALL);
$items = array ('name' => 'menu', 'children' => array ( 
        array ('name' => 'about', 'children' => array ('us', 'this-site' )), 
        array ('name' => 'links', 'children' => array ('external', 'internal')) 
    ) 
); 

function print_items ($items) { 
    echo '<ul>'; 
    foreach ($items as $item) { 
        echo '<li>'.$item['name']; 
        if (is_array($item['children'])) { 
           print_items ($item['children']); 
        } 
    } 
    echo '</ul>'; 
} 

print_items($items); 
?>

ik zal nog ff verder kijken..

Acties:
  • 0 Henk 'm!

  • X-Lars
  • Registratie: Januari 2004
  • Niet online

X-Lars

Just GoT it.

sorry :Z maybe tomorrow..

Acties:
  • 0 Henk 'm!

Verwijderd

Ik vrees dat het gezien de nogal lastige opzet van je array niet veel mooier kan dan dit:

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
function printItems($item, $base = TRUE)
{
    if ($base)
    {
        echo "<ul>\n";
        printItems($item, FALSE);
        echo "</ul>\n";
    }
    elseif (is_array($item))
    {
        if (isset ($item["name"]))
        {
            printItems($item["name"], FALSE);
            echo "<ul>\n";
            if (isset ($item["children"]))
            {
                foreach ($item["children"] as $child)
                {
                    printItems($child, FALSE);
                }
            }
            echo "</ul>\n";
        }
    }
    else
    {
        echo "<li>".$item."</li>\n";
    }
}


Om je functie mooier te kunnen gebruiken, moet je je array als volgt opzetten:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
$items = array ('name' => 'menu', 
                         'children' => array ( 
                         array ('name' => 'about', 
                                   'children' => array (
                                    array ('name' => 'us'), 
                                    array ('name' => 'this-site') )), 
                         array ('name' => 'links', 
                                    'children' => array (
                                    array ('name' => 'external'), 
                                    array('name' => 'internal') )) 
                          ) 
);

[ Voor 245% gewijzigd door Verwijderd op 05-02-2004 09:49 ]


Acties:
  • 0 Henk 'm!

  • WildernessChild
  • Registratie: Februari 2002
  • Niet online

WildernessChild

Voor al uw hersenspinsels

Is het niet gemakkelijker om dit object-georiënteerd op te lossen?
PHP:
1
2
3
4
5
6
7
class MenuNode {
  var $name;
  MenuNode children[];
  function print() {
    // printen die zooi
  }
}

Mijn PHP-syntax is een beetje roestig, dus waarschijnlijk klopt het niet precies, maar ik hoop dat je het idee begrijpt ;)

[ Voor 10% gewijzigd door WildernessChild op 05-02-2004 17:44 ]

Maker van Taekwindow; verplaats en resize je vensters met de Alt-toets!


Acties:
  • 0 Henk 'm!

  • Macros
  • Registratie: Februari 2000
  • Laatst online: 15-05 16:29

Macros

I'm watching...

Wat zeuren jullie nu allemaal?
Mijn eerste versie (eerste reply) werkt gewoon 100% goed.
Desnoods kan je dit er aan doen:
PHP:
1
2
3
4
5
6
7
8
9
10
11
function print_items ( $item , $name, $dep) { 
    if (is_array($item)){ 
        echo str_repeat(' ',$dep)."<ul>\n"; 
        foreach ($item as $name->$it) { 
            print_items($it, $name, $dep+1); 
        } 
        echo str_repeat(' ',$dep)."</ul>\n"; 
    } else { 
        echo str_repeat(' ',$dep)."[$name] $items \n"; 
    } 
}

Nu print hij ook de naam van een element erbij.

"Beauty is the ultimate defence against complexity." David Gelernter


Acties:
  • 0 Henk 'm!

  • Justice
  • Registratie: Maart 2001
  • Laatst online: 07-08 15:02
Marcos, er zat nog een foutje bij het ophogen van $dep, en de html klopte natuurlijk ook nog niet, maar onderstaand script werkt altijd goed :) Het maakt dus van een recursive associative array een html menu 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
<?php
//error_reporting(E_ALL); 
$menustructure_array = array ( 
    'name'      => 'menu', 
    'children'  => array 
    ( 
        array   ( 
            'name'      => 'about', 
            'children'  => array ( 
                'us',
                'this-site',
                'this-site' ,
                'this-site'  
            ) 
        ), 
        array ( 
            'name'      => 'links', 
            'children'  => array ( 
                'external', 
                'internal'
            ) 
        ) ,
        array ( 
            'name'      => 'links2', 
            'children'  => array ( 
                'external', 
                'internal'
            ) 
        ) 
    ) 
); 

function print_items ( $menustructure_array, $dep) { 
/* als het een array is */
    if (is_array($menustructure_array)) { 
    /* herhaal string $dep keer */
        echo str_repeat('  <ul>',$dep)."\n"; 
        /* voor elke item in array */
        foreach ($menustructure_array as $menu_item) { 
        /* start functie */
           print_items($menu_item, $dep+(1/count($menustructure_array))); 
        }       
        /* herhaal string $dep keer */
        echo str_repeat(' </ul>',$dep)."\n"; 
    } 
    /* geen array */
    else { 
       echo str_repeat('   ',$dep)."<li>".$menustructure_array. "</li>\n"; 
    } 
} 
echo '<ul>';
print_items ( $menustructure_array, $dep); 
echo '</ul>';
?>

Human Bobby


Acties:
  • 0 Henk 'm!

  • Macros
  • Registratie: Februari 2000
  • Laatst online: 15-05 16:29

Macros

I'm watching...

Thanks, ik ben geen html guru, verre van dat. Recursieve functies zijn leuk :)

"Beauty is the ultimate defence against complexity." David Gelernter


Acties:
  • 0 Henk 'm!

  • Justice
  • Registratie: Maart 2001
  • Laatst online: 07-08 15:02
En bedankt trouwens voor iedereen's antwoorden :)

Human Bobby

Pagina: 1