PHP Array Tree

Door Arian Stolwijk, 21 jaar geleden, 6.708x bekeken

Als je een pagina systeem wilt maken met oneindig veel subpagina's, kan deze class je van pas komen.

Ik maak er expres eerst een Array van, en dan pas een table. Je zou ook al veel eerder er meteen een table, ul/li list van kunnen maken, zoals hier.
Het nadeel hiervan is is echter dat je telkens een hele nieuwe class moet maken als je een keer andere html van wilt maken. Met deze array kan je met een simpele class, bijvoorbeeld die ik als voorbeeld helemaal onderaan geef, de array uitlezen. Ook kan je deze array bijvoorbeeld gebruiken als je Smarty gebruikt (http://smarty.incutio.com/?page=SmartyDocsErrorsAndSuggestions ctrl+f -> tree )

Dit is een voorbeeld van een SQL tabel:

CREATE TABLE paginas (
id int(10) auto_increment,
titel varchar(255),
menuid int(10),
parent int(10),
PRIMARY KEY (id)
);

Veel succes ermee.

ps. http://youmuppet.com/mootree/ dit kan je goed in combinatie met deze class gebruiken.

Gesponsorde koppelingen

PHP script bestanden

  1. php-array-tree

 

Er zijn 13 reacties op 'Onbekend'

PHP hulp
PHP hulp
0 seconden vanaf nu
 

Gesponsorde koppelingen
PHP erik
PHP erik
21 jaar geleden
 
0 +1 -0 -1
Ziet er op zich goed uit, alleen vind ik dit een beetje jammer: "PHP versie: 4". PHP 5 bestaat alweer meer dan 3 jaar.

"function printAdminTree()"
-> Dit moet zijn: function printArrayTree()

Mijn vraag: is dit niet slimmer met DOM te doen? Dan krijg je gewoon iets als:

$dom->element->subelement->subsubelement

En dan kun je er vanalles mee doen. Is maar een suggestie. Goed script verder! Bedankt.
Jelmer -
Jelmer -
21 jaar geleden
 
0 +1 -0 -1
Paar kleine dingetjes:
Kan je in Tree::maxLevel() niet gewoon "return max($this->levels) + 1;" gebruiken?

Zo ook Tree::getParents(), die kan volgens mij ook
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
function getParents($iId){
    $parent = array();
    $dad = $this->aElements[$iId]['parent'];
    
    while($dad = $this->getParent($dad)){
        $parent[] = $dad;
    }

    
    $this->aElements[$iId]['parents'] = $parent;
    return $parent;
}

?>

Gebruik je die entry 'parents' daarna eigenlijk nog?

Tree::getParent() snap ik ook niet helemaal. Je controleert eerst met empty en daarna nog een keer met != 0

Verder moet je Tree::level() verplicht aanroepen wil je Tree::maxLevel() kunnen gebruiken.

Ik vind het een leuk idee, maar je implementatie nog een beetje twijfelachtig.
Frank -
Frank -
21 jaar geleden
 
0 +1 -0 -1
Even over de tabel, waar is de foreignkey? Nu kun je een parent weggooien en daarmee direct de hele structuur naar de klote helpen.

foreignkey's in innoDB. Uiteraard innoDB, de rest van MySQL geeft geen donder om correcte data...
Arian Stolwijk
Arian Stolwijk
21 jaar geleden
 
0 +1 -0 -1
@PHPerik: printAdminTree() heb ik even veranderd in printArrayTree(). Zo heette namelijk de class in één van mijn pagina's.. ;)

Ja, ik denk dat het idd ook wel met DOM kan... zou alleen nog niet weten hoe... misschien een keer leuk om naar te kijken.

@Jelmer: Ik heb die != 0 en empty even veranderd. Nu is het gewoon alleen empty. Idd een beetje overbodig dingetje...
Ook met de functie getParents heb je gelijk, dat is inderdaad korter.
Het is ook waar dat je eerst Tree::level moet aanroepen voordat je Tree::maxLevel() kunt aanroepen. Als je Tree::getArray() aanroept gebeurd dat wel. maar wel een beetje tricky hè.. weet jij hoe ik dat beter kan doen??

@pgFrank. Je hebt inderdaad gelijk als je een parent verwijderd, dat hij dan in de war gaat. Ik zal eens naar Foreignkeys kijken... ;)

je moet dan zoiets doen ofniet ?
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
CREATE TABLE paginas (
   id INT,
   parent_id INT,
   FOREIGN KEY (parent_id) REFERENCES paginas(id)
   ON DELETE CASCADE,
   PRIMARY KEY(id)
) ENGINE=INNODB;

iig bedankt alvast voor de feedback... het was nog maar mijn eerste class, dus verwachte ik wel de nodige punten;):P
Frank -
Frank -
21 jaar geleden
 
0 +1 -0 -1
Yep, dat is hem. Test het maar even en kijk ook even of je de juiste/gewenste ON DELETE te pakken hebt. Ik zou bv. geen CASCADE willen gebruiken in dit geval, maar dat zegt niet zo veel.

Voeg ook nog even een ON UPDATE toe, voor het geval dat.
Arian Stolwijk
Arian Stolwijk
21 jaar geleden
 
0 +1 -0 -1
Ja, je zou dan SET DEFAULT of SET NULL kunnen gebruiken (=geen parent)
Frank -
Frank -
21 jaar geleden
 
0 +1 -0 -1
@Arian: Dit kan weer hele rare/ongewenste resultaten hebben, vooral die SET NULL. Eerst heb je een fraaie menu-structuur met zeg 8 parents. 1 van die parents heeft 30 children en nu gooi je de parent weg... Ik vrees dat nu je layout goed naar de bliksem is, ik ken weinig sites die in hun navigatie-structuur ineens met 37 parents uit de voeten kunnen.

Daarnaast ben je ieder verband kwijt, wanneer children dezelfde parent hebben, horen ze blijkbaar bij elkaar. Dat is nu niet meer het geval.

Ik zou er voor RESTRICT kiezen, dan wordt het onmogelijk om een parent weg te gooien zonder eerst de children een nieuwe plek te geven of weg te gooien. Dat is iets meer werk, maar stukken veiliger.

In je formulier kun je uiteraard een optie maken waarbij de user de keuze krijgt om automatisch eerst alle children weg te gooien en daarna ook de parent. Dan wordt verwijderen in elk geval een bewuste keuze. Voor zover users bewuste keuzes maken...
PHP erik
PHP erik
21 jaar geleden
 
0 +1 -0 -1
Sowieso RESTRICT of CASCADE ja. Het is maar wat je wil.
Arian Stolwijk
Arian Stolwijk
21 jaar geleden
 
0 +1 -0 -1
Naja, ik heb het nu iig zo als een pagina 0 als parent heeft, dan heeft het dus geen parent, dus is geen subpagina, dus hoofdpagina.

Dus als je dit bijvoorbeeld hebt...
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
id    |     parent
1           0
 - 2        1

en 1 wordt verwijderd, dan krijgt 2 toch als parent 0...
dus dan wordt het zo
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
id    |     parent
2           0

niks aan de hand toch??

of ik begrijp het nog niet helemaal. Dan zal ik nog even verder kijken, want het is opzich wel interressant.. :)
Frank -
Frank -
21 jaar geleden
 
0 +1 -0 -1
0 is wat anders dan NULL. En stel je voor dat 1 parent 30 children heeft. Verwijder vervolgens de parent, dan worden ineens alle children een parent! Vraag je even heel goed af of je dat wel wilt, dat zal meestal niet het geval zijn. Vandaar dat het meestal een beter plan is om of alle children ook weg te gooien (CASCADE) of de hele actie onmogelijk te maken (RESTRICT). Bij een RESTRICT zul je eerst alle children moeten verwijderen of een andere parent geven en dan pas kun je de originele parent verwijderen.
Kees Schepers
kees Schepers
21 jaar geleden
 
0 +1 -0 -1
Het is niet helemaal zoals ik het zou doen, ik zou sowieso een andere recursieve functie maken. Maar toch vind ik het er wel netjes / goed uitzien. T.o.z van alle scripts hier zou ik het een 7,5 geven.

Maar zoals al eerder gezegd werd; maak het in PHP5 zie het als een goed doel :) php4 is al zoooo oud....
Arian Stolwijk
Arian Stolwijk
21 jaar geleden
 
0 +1 -0 -1
@ Kees: Hoe zou jij het doen dan?? Ben ik wel even benieuwd ;)
PHP hulp
PHP hulp
0 seconden vanaf nu
 

Gesponsorde koppelingen
Peter maasse
peter maasse
19 jaar geleden
 
0 +1 -0 -1
dank !!!

Om te reageren heb je een account nodig en je moet ingelogd zijn.

Inhoudsopgave

  1. php-array-tree

Labels

  • Geen tags toegevoegd.

Navigatie

 
 

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.