[PHP + mySQL] Tree bouwen

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Hallo,

In mijn strijd om alsmaar verder te komen in PHP, ben ik nu voor een probleem gekomen waar ik geen goed antwoord voor kan vinden op internet. Ik heb me namelijk bedacht dat ik in mijn administratie een directory tree achtige structuur wil bouwen voor mijn categorieën en mijn subcategorieën. In de selectbox zou het er dan ongeveer zo uit moeten zien:

Hoofdcategorie (altijd id 0)
- subcategorie
- subcategorie
-- subcategorie
--- subcategorie
-- subcategorie
--- subcategorie
--- subcategorie
-- subcategorie
- subcategorie
- etc etc

Nu heb ik de volgende dataase structuur hiervoor gemaakt:

code:
1
2
3
4
5
6
7
8
CREATE TABLE KIEN_cat (
  id tinyint(4) NOT NULL auto_increment,
  parent_id tinyint(4) NOT NULL default '0',
  js char(1) NOT NULL default '',
  cs char(1) NOT NULL default '',
  name varchar(20) NOT NULL default '',
  PRIMARY KEY  (id)
) TYPE=MyISAM;



De parent_id geeft aan onder welke categorie de nieuwe categorie moet komen door naar de id van de categorie die geselecteerd is in de selectbox te kijken.

Nu lukt het me wel om dit te bouwen, maar heb ik het idee dat ik veel te veel query's uitvoer. Voor een administratie nog niet zo heel erg natuurlijk, maar ik wil dit ook in de navigatie op de site zelf toepassen. Dit is de code die ik tot nu toe geschreven heb om de tree uit te lezen:

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
  // query opbouwen
  $result1 = mysql_query("SELECT id, name FROM KIEN_cat WHERE parent_id = 0 ORDER BY name");
  //query uitvoeren in while loop
  while($query_data1 = mysql_fetch_row($result1)) {
    // als het script in edit mode opgeroepen wordt, dan moet de parent van de te editen categorie geselecteerd worden
    if ($query_data1[0] == $parent_id) $selected = " selected";
    // echo de optie voor de selectbox
    echo "                                  <option value=\"$query_data1[0]\"$selected>$query_data1[1]</option>\n";
    // voer op dit resultaat nog een query uit om te kijken of er categorieën onder deze categorie zitten
    $result2 = mysql_query("SELECT id, name FROM KIEN_cat WHERE parent_id = $query_data1[0] ORDER BY name");
    while($query_data2 = mysql_fetch_row($result2)) {
      if ($query_data2[0] == $parent_id) $selected = " selected";
      echo "                                  <option value=\"$query_data2[0]\"$selected>- $query_data2[1]</option>\n";
    }
  }


Bijkomend nadeel is dat ik voor ierdere verdieping in PHP ook nog eens opnieuw een query moet tikken. Als er dus meer verdiepingen zijn dan query's, zal hij dus niet alles weergeven. Hoe kan ik dit optimaliseren?

Acties:
  • 0 Henk 'm!

  • gorgi_19
  • Registratie: Mei 2002
  • Laatst online: 18-09 17:06

gorgi_19

Kruimeltjes zijn weer op :9

[rml][ Php/mysql] recursief tree weergeven *[/rml]

Met die titel als zoekwoorden moet je ook wel eea kunnen vinden. :)

Digitaal onderwijsmateriaal, leermateriaal voor hbo


Acties:
  • 0 Henk 'm!

  • djc
  • Registratie: December 2001
  • Laatst online: 08-09 23:18

djc

http://www.sitepoint.com/article/1105

Een andere manier om je tree op te bouwen in de database, die in dit soort gevallen wel goed schijnt te werken. ;)

Rustacean


Acties:
  • 0 Henk 'm!

Verwijderd

Ik heb ook eens een structuur aangemaakt zoals jij nu beschrijft, alleen dan met berichten (reacties) die oneindig diep genest konden worden.
Ik heb toen een algoritme bedacht dat de berichten goed sorteerde. Ik gebruikt dus maar 1 query om de data op te halen.
Wellicht dat je er wat aan hebt:

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
                while($reply = mysql_fetch_array($_reply))
                {
                    $replies[] = $reply;
                }

                for($i = 0; $i < sizeof($replies); $i++)
                {
                    if($replies[$i]["parentid"] == 0)
                    {
                        $j = sizeof($replies_sort);
                        $replies_sort[] = array();

                        while($j > 0)
                        {
                            $replies_sort[$j] = $replies_sort[$j-1];
                            $reply_keys[$replies_sort[$j]["id"]]++;
                            $j--;
                        }

                        $replies_sort[0] = $replies[$i];
                        $reply_keys[$replies[$i]["id"]] = 0;
                    }
                    else
                    {
                        $j = sizeof($replies_sort);
                        $replies_sort[] = array();
                        $parent_key = $reply_keys[$replies[$i]["parentid"]];
                        $dest_key = $parent_key + 1;

                        while($j > $dest_key)
                        {
                            $replies_sort[$j] = $replies_sort[$j-1];
                            $reply_keys[$replies_sort[$j]["id"]]++;
                            $j--;
                        }

                        $replies_sort[$dest_key] = $replies[$i];

                        $reply_keys[$replies[$i]["id"]] = $dest_key;
                    }
                }

Ik heb er irrelevante dingen eruit geknipt, maar zo zou het moeten werken. $_reply is dus het resultaat van de SELECT-query, waarin alle replies worden opgehaald. Elke reply waarvan de parentid gelijk aan 0 (nul) is, is in feite een nieuwe thread.
Ik hoop dat je er wat aan hebt.

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Thnx allemaal! Ik ben eruit :)