Een simpele boomstructuur

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Pieters mieters

pieters mieters

22/09/2014 13:52:13
Quote Anchor link
Hoi, ik weet niet zeker of mijn post hier of bij beginners hoort, dus alvast mijn excuus als ik verkeerd gekozen heb.

Ik zit met een klein probleempje dat het mij maar niet lukt om de juiste mysql structuur of php code te schrijven om een boomstructuur vanuit parent>child relatie op het scherm te krijgen.

ik werk met de volgende mysql database structuur (onderwerpnaam1 e.d. zijn placeholders voor willekeurige titels en namen,.. zie mijn laatste post):
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
database:
onderwerpen
onderwerpnaam1
onderwerpnaam1_index
onderwerpnaam2
onderwerpnaam2_index
..etc

onderwerpen
autoID | onderwerp
1       | onderwerpnaam1         
2      | onderwerpnaam2        
3      | onderwerpnaam3        

onderwerpnaam1:
autoID | onderwerpnaam1 | andere info
1      | onderwerp1        | ..
2      | onderwerp2        | ..
3      | onderwerp3        | ..
4      | onderwerp4        | ..

onderwerpnaam1_index
autoID | onderwerpnaamID | ouder_onderwerpID | ouderID
1       | 1                 | 2                 | 1
2      | 2               | 4                 | 2
3      | 3               | 5                 | 2


en de php code die ik gebruik is als volgt:
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
<?php
require ($_SERVER["DOCUMENT_ROOT"]."/onderdelen/db_verbinding.php");

$betreftnaam = "willekeurige_onderwerpnaam";
$betreftnaamID = $betreftnaam."ID";
$betreftnaam_index = $betreftnaam."_index";
$resultaat = mysqli_query($verbinding,"SELECT autoID FROM onderwerpen WHERE onderwerp = '$betreftnaam'")  or die(mysql_error());
$rij = mysqli_fetch_array( $resultaat );
mysqli_free_result( $resultaat );
$ouder_onderwerpID = $rij['autoID'];

$resultaat = mysqli_query( $verbinding,"SELECT autoID, $betreftnaam FROM $betreftnaam ORDER BY autoID" ) or die(mysql_error());
while( $rij=mysqli_fetch_row($resultaat) )
    {

    $autoIDrij[] = $rij[0];
    $betreftrij[] = $rij[1];
    };

mysqli_free_result($resultaat);
foreach( $autoIDrij as $autoID )
    {

    $betreft = $betreftrij[$autoID - 1]; //eerste autoID = 1, eerste rij is 0.
    echo "(".$autoID.")".$betreft."<br>";
    $ouderID = $autoID;
    unset($autoIDrij);
    $resultaat = mysqli_query( $verbinding,"SELECT autoID, onderwerp FROM onderwerpen ORDER BY autoID" ) or die(mysql_error());
    while( $rij=mysqli_fetch_row($resultaat) )
        {

        $autoIDrij[] = $rij[0];
        $onderwerprij[] = $rij[1];
        };

    mysqli_free_result($resultaat);
    foreach( $autoIDrij as $autoID )
        {

        $onderwerpnaam = $onderwerprij[$autoID - 1]; //eerste autoID = 1, eerste rij is 0.
        $onderwerpnaamID = $onderwerpnaam."ID";
        $onderwerpnaam_index = $onderwerpnaam."_index";
// ----------------------<<
        $resultaat = mysqli_query($verbinding,"SELECT $onderwerpnaamID FROM $onderwerpnaam_index WHERE ouderID = '$ouderID' AND ouder_onderwerpID = '$ouder_onderwerpID'") or die(mysql_error());
        while( $rij=mysqli_fetch_row($resultaat) )
            {

            $onderwerpIDrij[] = $rij[0];
            };

        mysqli_free_result($resultaat);
        if (!empty($onderwerpIDrij))
            {

            foreach( $onderwerpIDrij as $onderwerpID )
                {

                $resultaat = mysqli_query($verbinding,"SELECT $onderwerpnaam FROM $onderwerpnaam WHERE autoID = '$onderwerpID'") or die(mysql_error());
                $rij = mysqli_fetch_array( $resultaat );
                mysqli_free_result( $resultaat );
                $onderwerp = $rij[$onderwerpnaam];
                echo $onderwerp."<br>";
//// ----------------------
//Het probleem is dat ik hier voor iedere laag dieper in de boom het stuk code tussen de '// ----------------------<<'-strepen moet herhalen.
//Dit werkt alleen als ik weet hoe diep de boom is, maar dat is onbekend.
//// ----------------------

                };
            unset($onderwerpIDrij);
            };
        };

// ----------------------<<
    unset($autoIDrij);
    };

mysqli_close($verbinding);
?>


Het probleem dat ik heb is dat ik voor iedere laag in de boom een commando moet uitvoeren, en er maar niet uit kom hoe ik dit kan loopen zodat hij net zo lang door gaat tot alle lagen van de boom zijn weergegeven. Ik vermoed echter dat ik gewoon totaal op het verkeerde spoor zit, maar dit was het beste waar ik vooralsnog op kon komen :P

ik hoop dat iemand me op weg wil helpen en me kan uitleggen hoe ik dit oplos.
Gewijzigd op 23/09/2014 19:54:21 door Pieters mieters
 
PHP hulp

PHP hulp

05/12/2022 13:41:06
 
Eddy E

Eddy E

22/09/2014 14:19:14
Quote Anchor link
Je haalt je complete menu/lijst op. Gewoon in 1 while-loop.

In je while-loop kijk je of het voorgaand record (die moet je dus even tijdelijk opslaan in een $variabele) de parent is van het huidige record. Zo nee: vorige <ul> sluiten (als die er is!) en extra <ul> of <ol> starten.
De rest gooi je gewoon in een <li>



Toevoeging op 22/09/2014 14:19:41:

Kijk even op: http://stackoverflow.com/questions/18063291/nested-lists-in-php-and-mysql

Toevoeging op 22/09/2014 14:20:14:

Of: http://stackoverflow.com/questions/18706007/how-to-create-nested-category-list-from-category-strings-in-php

Engels: nested list php / sql
 
Pieters mieters

pieters mieters

22/09/2014 15:14:44
Quote Anchor link
De twee links gaan beide over een array met een vaststaand aantal lagen,
Mijn boom moet echter een onbekend aantal lagen weergeven, en kan op alle niveaus meerdere takken krijgen, en onderwerpen kunnen op meerdere plaatsen in de boom staan. Ik heb daarom de indruk dat het misschien niet de oplossing is (maar ik ben de voorbeelden nog aan het bestuderen, ik ben een behoorlijke beginneling dus ik snap er nog niet heel veel van :)
Gewijzigd op 22/09/2014 15:19:43 door pieters mieters
 
Frank Nietbelangrijk

Frank Nietbelangrijk

22/09/2014 16:42:41
Quote Anchor link
In ieder geval ben je verkeerd bezig als je tabel- of kolomnamen moet gaan nummeren.

onderwerpnaam1:
onderwerpnaam2:
onderwerpnaam3:

Moet gewoon worden:

onderwerpnamen.

in deze tabel komt dan een kolom 'onderwerp_id' die refereert naar het juiste autoID in de tabel onderwerpen.
 
Pieters mieters

pieters mieters

22/09/2014 17:50:40
Quote Anchor link
Oei sorrie, dan ben ik niet duidelijk genoeg geweest. Ik heb niets genummerd, maar alles is dynamisch en de namen zijn niet bij voorbaad bekend. Het zou er dus ongeveer zo uit kunnen zien:
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
75
76
77
database:
onderwerpen
gebieden
gebieden_index
dieren
dieren_index
voedsel
voedsel_index
..etc
---------------------------------------



onderwerpen: (Het autoID van deze tafel is ouder_onderwerpID)
autoID | onderwerp
1      | gebieden
2      | dieren
3      | voedsel

gebieden: (Het autoID van deze tafel is ouderID en gebiedenID)
autoID | gebieden  | andere info
1      | wei       | ..
2      | meer      | ..
3      | huis      | ..
4      | lucht     | ..
5      | kooi      | ..

gebieden_index:  (Het autoID van deze tafel is ouder_indexID)
autoID | gebiedenID | ouder_onderwerpID | ouderID
1      | 1          | 0                 | 0
2      | 2          | 0                 | 0
3      | 3          | 0                 | 0
4      | 4          | 0                 | 0
5      | 5          | 1                 | 3


dieren: (Het autoID van deze tafel is ouderID en dierenID)
autoID | dieren | andere info
1      | kat    | ..
2      | koe    | ..
3      | vis    | ..
4      | vogel  | ..
5      | schaap | ..

dieren_index: (Het autoID van deze tafel is ouder_indexID)
autoID | dierenID | ouder_onderwerpID | ouderID
1      | 1        | 1                 | 3
2      | 2        | 1                 | 1
3      | 3        | 1                 | 2
4      | 4        | 1                 | 4
5      | 5        | 1                 | 1
6      | 4        | 1                 | 5


voedsel: (Het autoID van deze tafel is ouderID en voedselID)
autoID | voedsel   | andere info
1      | algen     | ..
2      | wormen    | ..
3      | gras      | ..
4      | muizen    | ..

voedsel_index: (Het autoID van deze tafel is ouder_indexID)
autoID | voedselID | ouder_onderwerpID | ouderID
1      | 1         | 2                 | 3
2      | 2         | 2                 | 4
3      | 3         | 2                 | 2
4      | 3         | 2                 | 5
5      | 4         | 2                 | 1



wei - koe - gras
wei - schaap - gras
meer - vis - algen
huis - kat - muizen
huis - kooi - vogel - wormen
lucht - vogel - wormen

en in de php is de eerste regel dan bv:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
$betreftnaam = "gebieden";


Toevoeging op 22/09/2014 20:08:13:

Omdat ik in eerste instantie niet duidelijk genoeg ben geweest heb ik ook de php code wat opgeschoond en uitgewerkt tot niveau 0, 1 en 2 (ipv 0, 1). Daarnaast heb ik de gebieden afgekaderd die de code per niveau beschrijven. ie. Als je weghaalt wat tussen "// a----------------------" staat, is alleen de code voor niveau 0 over. Als je weghaalt wat tussen "// b----------------------" staat, is alleen de code voor niveau 0 en 1 over, en als er een niveau bij moet komen, dan moet het deel van tussen "// b----------------------", tussen "// c----------------------" gezet worden.
en ik heb geen idee hoe ik hier een while loop omheen doe.
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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
<?php
require ($_SERVER["DOCUMENT_ROOT"]."/onderdelen/db_verbinding.php");

$betreftnaam = "gebieden"; //($_POST['bn']);
$betreftnaamID = $betreftnaam."ID";
$betreftnaam_index = $betreftnaam."_index";
$resultaat = mysqli_query($verbinding,"SELECT autoID FROM onderwerpen WHERE onderwerp = '$betreftnaam'")  or die(mysql_error());
$rij = mysqli_fetch_array( $resultaat );
mysqli_free_result( $resultaat );
$ouder_onderwerpID = $rij['autoID'];
$resultaat = mysqli_query( $verbinding,"SELECT autoID, $betreftnaam FROM $betreftnaam ORDER BY autoID" ) or die(mysql_error());
while( $rij=mysqli_fetch_row($resultaat) )
    {

    $autoIDrij[] = $rij[0];
    $betreftrij[] = $rij[1];
    };

mysqli_free_result($resultaat);
foreach( $autoIDrij as $autoID )
    {

    $betreft = $betreftrij[$autoID - 1]; //eerste autoID = 1, eerste rij is 0.
    echo "niveau0=".$betreft."<br>";
    $ouderID = $autoID;
// a----------------------
    unset($autoIDrij);
    $resultaat = mysqli_query( $verbinding,"SELECT autoID, onderwerp FROM onderwerpen ORDER BY autoID" ) or die(mysql_error());
    while( $rij=mysqli_fetch_row($resultaat) )
        {

        $autoIDrij[] = $rij[0];
        $onderwerprij[] = $rij[1];
        };

    mysqli_free_result($resultaat);
    foreach( $autoIDrij as $autoID )
        {

        $onderwerpnaam = $onderwerprij[$autoID - 1]; //eerste autoID = 1, eerste rij is 0.
        $onderwerpnaamID = $onderwerpnaam."ID";
        $onderwerpnaam_index = $onderwerpnaam."_index";
        $resultaat = mysqli_query($verbinding,"SELECT $onderwerpnaamID FROM $onderwerpnaam_index WHERE ouderID = '$ouderID' AND ouder_onderwerpID = '$ouder_onderwerpID'") or die(mysql_error());
        while( $rij=mysqli_fetch_row($resultaat) )
            {

            $onderwerpIDrij[] = $rij[0];
            };

        mysqli_free_result($resultaat);
        if (!empty($onderwerpIDrij))
            {


            foreach( $onderwerpIDrij as $onderwerpID ) //voor alle onderwerpen
                {
                $resultaat = mysqli_query($verbinding,"SELECT $onderwerpnaam FROM $onderwerpnaam WHERE autoID = '$onderwerpID'") or die(mysql_error());
                $rij = mysqli_fetch_array( $resultaat );
                mysqli_free_result( $resultaat );
                $onderwerp = $rij[$onderwerpnaam];
                echo "niveau1=".$onderwerp."<br>";

                $resultaat = mysqli_query($verbinding,"SELECT autoID FROM onderwerpen WHERE onderwerp = '$onderwerpnaam'")  or die(mysql_error());
                $rij = mysqli_fetch_array( $resultaat );
                mysqli_free_result( $resultaat );
                $ouder_onderwerpID2 = $rij['autoID'];
                $ouderID2 = $onderwerpID;
// b----------------------
                $resultaat = mysqli_query( $verbinding,"SELECT autoID, onderwerp FROM onderwerpen ORDER BY autoID" ) or die(mysql_error());
                while( $rij=mysqli_fetch_row($resultaat) )
                    {

                    $autoID2rij[] = $rij[0];
                    $onderwerp2rij[] = $rij[1];
                    };

                mysqli_free_result($resultaat);
                foreach( $autoID2rij as $autoID2 ) //voor alle onderwerpen
                    {
                    $onderwerpnaam2 = $onderwerp2rij[$autoID2 - 1]; //eerste autoID = 1, eerste rij is 0.
                    //echo ".(".$autoID.")".$onderwerpnaam."<br>";

                    $onderwerpnaam2ID = $onderwerpnaam2."ID";
                    $onderwerpnaam2_index = $onderwerpnaam2."_index";

                    $resultaat = mysqli_query($verbinding,"SELECT $onderwerpnaam2ID FROM $onderwerpnaam2_index WHERE ouderID = '$ouderID2' AND ouder_onderwerpID = '$ouder_onderwerpID2'") or die(mysql_error());
                    while( $rij=mysqli_fetch_row($resultaat) )
                        {

                        $onderwerpID2rij[] = $rij[0];
                        };

                    mysqli_free_result($resultaat);
                    unset($autoID2rij);

                    if (!empty($onderwerpID2rij))
                        {


                        foreach( $onderwerpID2rij as $onderwerpID2 ) //voor alle onderwerpen
                            {
                            $resultaat = mysqli_query($verbinding,"SELECT $onderwerpnaam2 FROM $onderwerpnaam2 WHERE autoID = '$onderwerpID2'") or die(mysql_error());
                            $rij = mysqli_fetch_array( $resultaat );
                            mysqli_free_result( $resultaat );
                            $onderwerp2 = $rij[$onderwerpnaam2];
                            echo "niveau2=".$onderwerp2."<br>";
// c----------------------

// c----------------------

                            };
                        unset($onderwerpID2rij);
                        };
                    };

// b----------------------
                };
            unset($onderwerpIDrij);
            };
        };

// a----------------------
    unset($autoIDrij);
    };

mysqli_close($verbinding);
?>

Ik hoop dat het zo wat duidelijker is wat ik bedoel.

Toevoeging op 22/09/2014 22:15:39:

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
<?php
require ($_SERVER["DOCUMENT_ROOT"]."/onderdelen/db_verbinding.php");


$i=0;
$lus=1;
while ($lus == 1)
    {

//b-----------------    
    $betreftnaam[$i] = "gebieden"; //($_POST['bn']);
    $betreftnaamID[$i] = $betreftnaam[$i]."ID";
    $betreftnaam_index[$i] = $betreftnaam[$i]."_index";
    $resultaat = mysqli_query($verbinding,"SELECT autoID FROM onderwerpen WHERE onderwerp = '$betreftnaam[$i]'")  or die(mysql_error());
    $rij = mysqli_fetch_array( $resultaat );
    mysqli_free_result( $resultaat );
    $ouder_onderwerpID[$i] = $rij['autoID'];

    $resultaat = mysqli_query( $verbinding,"SELECT autoID, $betreftnaam[$i] FROM $betreftnaam[$i] ORDER BY autoID" ) or die(mysql_error());
    while( $rij=mysqli_fetch_row($resultaat) )
        {

        $autoIDrij[] = $rij[0];
        $betreftrij[] = $rij[1];
        };

    mysqli_free_result($resultaat);
    foreach( $autoIDrij as $autoID )
        {

        $betreft[$i] = $betreftrij[$autoID - 1]; //eerste autoID = 1, eerste rij is 0.
        echo "niveau".$i."=".$betreft[$i]."<br>";
        $ouderID[$i] = $autoID;
//c-----------------
//c-----------------

        unset($autoIDrij);
        };

//b-----------------    
    $i++;
    $lus=0;
    };
//while
mysqli_close($verbinding);
?>


Volgens mij ben ik zo op de goede weg.
Het probleem is alleen nog steeds dat het volgende niveau een loop betreft van dat wat tussen //b----- staat, tussen //c--- moet komen te staan, maar dat is midden in de loop van //b------ en daarom kan ik het niet als geheel loopen (dus dit stukje code valt er dan buiten)
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
        unset($autoIDrij);
        };
Gewijzigd op 22/09/2014 22:18:03 door pieters mieters
 
Pieters mieters

pieters mieters

23/09/2014 19:55:36
Quote Anchor link
Ik ben er zo goed als uit, als het klaar is post ik het hier nog even zodat men er evt wat aan heeft. Bedankt voor het meedenken :)
 
Pieters mieters

pieters mieters

26/09/2014 19:39:47
Quote Anchor link
Helaas. Het blijkt (voor mij) onmogelijk te zijn.

De officiele manieren in de vorm van nested sets blijken allemaal in diepte beperkt te zijn. Daarnaast heeft iedere ouder slechts 1 kind en kunnen die niet onder meerdere ouders verdeeld zijn.
Mijn vraag naar een makkelijke boomstructuur blijkt dus een vraag naar een moeilijke boomstructuur geweest te zijn.
 
Tim S

Tim S

26/09/2014 20:36:31
 
Pieters mieters

pieters mieters

26/09/2014 21:15:39
Quote Anchor link
Dat ziet er interessant uit, daar ga ik morgen met een fris hoofd eens goed naar kijken. (zo op het eerste gezicht lijkt deze zich jammergenoeg ook te beperken tot ongedeelde kinderen. ik heb kinderen die in meerdere bomen, in meerdere takken, en op verschillende niveaus voor kunnen komen, maar wie weet, iig alvast heel erg bedankt :)
 
Frank Nietbelangrijk

Frank Nietbelangrijk

26/09/2014 22:27:58
Quote Anchor link
Ik had ook een artikel dat ik zelf erg intressant vind: http://www.phpbuilder.com/articles/databases/mysql/handling-hierarchical-data-in-mysql-and-php.html

Toevoeging op 26/09/2014 22:38:52:

google ook eens op 'php class for nested set' en je zult zien dat er kant en klare php code beschikbaar is om hierarchical data van/naar de database toe te passen.
Gewijzigd op 27/09/2014 11:15:13 door Frank Nietbelangrijk
 
Pieters mieters

pieters mieters

28/09/2014 10:59:27
Quote Anchor link
Ik heb er nog even goed naar gekeken maar ik heb toch echt mijn grens bereikt en neem vooralsnog genoegen met de bruteforcevarriant van hierboven en dan in 4 lagen.
Hetgeen ik maak hoeft slechts dusdanig functioneel te zijn dat ik het als presentatie kan gebruiken richting een echte programmeur dus wat dat betreft kom ik er ook zo wel.

(overigens denk ik dat ik het antwoord al wel ergens gevonden heb, alleen kon ik er zo niet heel veel mee (alsin, overschakelen zou een evengroot blok aan mijn been zijn geweest.)
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
$list = array(...);
$nested = array();

foreach ($list as $item)
{
    if ($item['parent_id'] == 0)
    {
        // Woot, easy - top level
        $nested[$item['id']] = $item;
        echo "id=".$item['id']."<br>";
        echo "parent_id=". $item['parent_id']."<br>";
        echo "text=". $item['text']."<br>";
    }
    else
    {
        // Not top level, find it's place
        process($item, $nested);
        echo "id=". $item['id']."<br>";
        echo "parent_id=". $item['parent_id']."<br>";
        echo "text=". $item['text']."<br>";
    }
}

// Recursive function
function process($item, &$arr)
{
    if (is_array($arr))
    {
        foreach ($arr as $key => $parent_item)
        {
            // Match?
            if (isset($parent_item['id']) && $parent_item['id'] == $item['parent_id'])
            {
                $arr[$key]['children'][$item['id']] = $item;
            }
            else
            {
                // Keep looking, recursively
                process($item, $arr[$key]);
            }
        }
    }
}

?>



Als het goed is, is dit in diepte onbeperkt.(maar weer geen dubbele takken)

Bedankt iedereen!:D
Gewijzigd op 28/09/2014 11:00:26 door pieters mieters
 



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.