[PHP4] Tree structuur: children verdwijnen

Pagina: 1
Acties:

  • st0p
  • Registratie: April 2004
  • Laatst online: 19-07-2024
Ik zit met het volgende probleem: Ik wil in PHP een menustructuur maken. De menuitems komen uit een database en bevatten een ID en een Parent. Nou zit ik met het probleem dat alles wat niet direct onder de 'root' hangt gewoonweg vedwijnt. even schematisch:

0
|
+-1
| +3
+-2
+4
+5

De items 3, 4 en 5 verdwijnen dus gewoon.

PHP:
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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
<?php

class MenuItem{
    var $id;
    var $name;
    var $parent;
    var $ordering;
    var $link;
    var $children;
    
    function MenuItem($i, $n, $p, $o, $l) {
        $this->id           = $i;
        $this->name         = $n;
        $this->parent   = $p;
        $this->ordering     = $o;
        $this->link         = $l;
        $this->children     = array();
    }
    
    function MenuPrint($spacing) {
        echo $spacing . $this->name . "<br>";
        $newspacing = $spacing .  " ";
        foreach ($this->children as $child) {
            $child->MenuPrint($newspacing);
        }            
    }
     
    function AddChild($newchild) {
        if ($newchild->parent == $this->id) {
            array_push($this->children, &$newchild);
            return 1;
        } else {
            foreach($this->children as $child) {
                if ($child->AddChild(&$newchild)) { 
                    return 1;
                }
            }
            return 0;               
        } 
    }
    
    function &GetChild($id) {
        if ($this->id == $id) {
            return $this;
        } elseif (count($this->children) == 0) {
            return NULL;
        } else {
            foreach ($this->children as $child) {
                $ret = &$child->GetChild($id);
                if (!is_null($ret)) {
                    return $ret;
                }
            }
            return NULL;
        }
    }

$link = mysql_connect('localhost', '****', '****') 
    or die ('Could not connect: ' . mysql_error());
mysql_select_db('helpdesk') 
    or die('Could not select database');

// Performing SQL query
$query  = 'select id, name, parent, link, ordering from jos_menu where menutype="mainmenu" order by id, parent, ordering;';
$result = mysql_query($query) or die('Query failed: ' . mysql_error());

//create a root menuitem.
$menuroot = new MenuItem(0, "root", 0, 0, "http://noppes");
$notfound = array();

//first cycle, will push all the top level menuitems into the menuroot. All other items
//will be pushed onto the not-found array. 
while ($line = mysql_fetch_array($result, MYSQL_ASSOC)) {
    if ($line['parent'] == 0) {
        $newchild = &new MenuItem($line['id'], $line['name'], 0, $line['ordering'], $line['link']);
        $menuroot->AddChild(&$newchild);
    } else {
        array_push($notfound, $line);
    }
}

//let's cycle through the not found collection and see what we can do with it.
for ($i = count($notfound) - 1; $i >= 0; $i--) {
    $line = $notfound[$i];
    $newchild = &new MenuItem($line['id'], $line['name'], $line['parent'], $line['ordering'], $line['link']);
    $test = $menuroot->GetChild($line['parent']);
    if (!is_null($test))
        $test->AddChild(&$newchild);
    //TODO: Remove from not-found array when the parent of the item is found. 
} 

mysql_free_result($result);
mysql_close($link);
?>


Okay, dit is dus een eerste versie, er zitten nog tig verbeter punten in en dat weet ik }:O
Maar zolang de 'kleinkinderen' verdwijnen heeft het weinig zin om te verbeteren :9
het bizarre is dat als je in de loop zelf (bijvoorbeeld op regel 92) een menuroot->MenuPrint(" ") doet het laatst toegevoegde item wel geprint word (eerder toegevoegde items zijn dan weer weg). valt het nieuwe item soms buiten de scope oid?

  • Helza
  • Registratie: Maart 2003
  • Laatst online: 17-12-2025
Je doet op verschillende plekken het volgende:

foreach($this->children as $child) {}

$child = een kopie van het originele object.. niet het origineel..
Omdat je met een kopie werkt wordt deze telkens overschreven door het volgende kind en voeg je dus nooit echt iets toe aan de array objecten in $this->children

  • st0p
  • Registratie: April 2004
  • Laatst online: 19-07-2024
Dankjewel, het vervangen van de foreaches is inderdaad de oplossing :)