PHP5 Array2Nested v1.1.2

Door Roland F, 19 jaar geleden, 5.056x bekeken

Ik las op PHPFreakz onlangs een topic waarin gevraagd werd hoe je data kan omzetten naar geneste data zodat je bv categorieën eindeloos kunt nesten in een forum, webshop etc.

Met dat idee en te veel vrije tijd tijdens de kerstdagen ben ik begonnen aan een class/module om het hele recursieve nesten ietwat te automatiseren.

Het nesten gebeurd zoals genoemd recursief a.d.h.v. een id/parent combinatie binnen een array.

Ondanks dat ik dat ik tijdens het maken van deze class pas op de hoogte werd gesteld van de left/right methode (http://www.sitepoint.com/article/hierarchical-data-database/2/), heb ik toch besloten om aan de recursieve methode vast te houden. Dit maakt het werken met objecten van _directe_ kinderen veel eenvoudiger. Daarnaast is het in de praktijk onwaarschijnlijk dat je tot diepte 1000+ gaat nesten.

Uiteraard mogen mensen zich melden die zich interesseren voor het implementeren van een layer optie in deze module. Iets als;
abstract Nested_Nest, Nested_Nest_Recursive, Nested_Nest_LeftRight
Het is uiteraard wel essentieel dat de recursieve werking van de module blijft werken. (Nested::getRoot()->firstChild()->firstChild()[->...])

Getest op:
PHP 5.2.4

Versie:
1.1.2

Bestanden:
Nested_Example.php, Nested.php, Nested_Child.php, Nested_Exception.php

Output voorbeeld:
http://www.devarea.nl/roland-tmp/Nested_Example.png

Geplaatst op:
PHPFreakz, PHPHulp, Sitemasters

Changelog:
v1.1.2 [30-12-08]
* Nested::sortAll toegevoegd om de kinderen van elk item tegelijk hetzelfde te sorteren
* Nested_Child::getIndex() toegevoegd
* Nested_Child::randomChild/childById/childByIndex toegevoegd
* Nested_Child::isChild/getChild verwijderd
* Nested_Output verwijderd; HTML implementatie is niet te globaliseren - opnieuw voorbeeld toegevoegd voor geneste HTML list

v1.1.1 [28-12-08]
* Nested::getFlat() aangepast; Nested::getFlat() -> array(id => Nested_Child); Nested::getFlat(true) -> array(id => array(row_data))
* Nested::MAX_DEPTH ident toegevoegd; elk kind lager als n bepaalde diepte wordt kind van de vorige parent (0 = unlimited)
* Performance update: diepte wordt niet meer berekend door de 'ancestors' te tellen maar direct bij het nesten
* Nested_Child::isMaxDepth() toegevoegd om te controleren of een kind zich in de maximale diepte bevindt
* Kinderen sorteren gebeurd nu via het 'natural ordering algorithm', zodat 'Titel 10' na 'Titel 9' komt (ASC)

v1.1.0 [27-12-08]
* Nested_Child::FLAG_LIMIT toegvoegd om het aantal kinderen via Nested_Child::getChildren() te limieten
* Nested::__toString/toHtml, Nested_Child::__toString/toHtml en Nested_Output toegvoegd (zie voorbeeld)

v1.0.0 [26-12-08]
* dump

Voorbeeld: http://www.devarea.nl/roland-tmp/Nested_Example.png

Gesponsorde koppelingen

PHP script bestanden

  1. php5-array2nested-v112

 

Er zijn 10 reacties op 'Onbekend'

PHP hulp
PHP hulp
0 seconden vanaf nu
 

Gesponsorde koppelingen


19 jaar geleden
 
0 +1 -0 -1
Mooi script! Wilde eigenlijk net beginnen zelf zoiets te maken, maar nu gebruik ik dit script. Scheelt een hoop tijd!
Roland F
Roland F
19 jaar geleden
 
0 +1 -0 -1
Class verder uitgebreid met output mogelijkheden (Zie voorbeeld).

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
<?php
$nested
= new Nested($data);
$output = new Nested_Output('myMethodSuffix'); // called Nested_Output::_output_myMethodSuffix($the_child)

echo $nested->toHtml($output);
?>


19 jaar geleden
 
0 +1 -0 -1
Er leuke class denk dat ik hem ga gebruiken voor het nesten van categorieën.

Misschien nog een leuke toevoeging dat je kunt zeggen dat er maar genest mag worden tot bijvoorbeeld level3 en dat daarna alle waardes die nog dieper gaan gezien worden als een child van level 3. Waarbij uiteraard wel gelet wordt op de goeie volgorde... Dit zou men bijvoorbeeld dan simpel kunnen toepassen bij een reactie systeem waarbij men zeg maar 'quote' door te reageren op het bericht. Zie tweakers bijvoorbeeld ;)
Roland F
Roland F
19 jaar geleden
 
0 +1 -0 -1
Ik ben nu bezig met Nested::MAX_DEPTH een ident om dus de maximale diepte in te stellen.

Voer versie 1.1.1 een deze dagen door met nog wat meer 'fixes'/verbeteringen/etc.

// edit;
Het werkt :-] Nog even over je opmerking op het sorteren; alle data wordt genest in Nested::Nest() (ook met MAX_DEPTH in 1.1.1), de volgorde waarin kinderen toegevoegd worden is dus compleet afhankelijk van de volgorde waarin ze binnenkomen. Als de rauwe data dus uit een database komt en je hebt ORDER BY gebruikt wordt die volgorde gehandhaafd. Je kunt dit later weer aanpassen met Nested_Child::sortChildren() uiteraard.


19 jaar geleden
 
0 +1 -0 -1
Wat helemaal mooi zou zijn is een optie om een gedeelte "dicht te vouwen". Dit zou handig zijn in bijvoorbeeld een menu, waarvan je alleen het gedeelte uitgevouwen toont van de pagina waarop je bent.
Roland F
Roland F
19 jaar geleden
 
0 +1 -0 -1
Werkelijk togglen (open/dicht) doe je met Javascript en valt compleet buiten deze class.

Van te voren bepalen of childs geshowed moeten worden of niet behoor je eigenlijk ook zelf te implementeren; ik weet niet hoe jouw app eruit ziet.

Deze class is slechts een helper om het hele zaakje wat netter in je app te verwerken. Dit is ook precies de reden waarom ik eigenlijk niet aan Nested_Output wou beginnen, ik kan niet bepalen hoe iemand iets in zijn app geimplementeerd wil hebben, maar omdat anders voor de beginners het doel van dit script helemaal compleet zou ontgaan heb ik dat er toch nog maar ingebouwd.

Nogmaals; wil je dat een bepaald kind dicht blijft zul je dit zelf moeten verwerken met iets als
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
<?php
foreach($nested->getRoot()->getChildren() as $child) {
    if($child->getId() == $my_id_value) {
        continue; // whatever.. net wat je wilt
    }
    // de rest
}
?>


19 jaar geleden
 
0 +1 -0 -1
Ja okee, daar heb je gelijk in. Ik bedoelde sowieso ook geen javascript. Ik knutsel nog wel wat.


19 jaar geleden
 
0 +1 -0 -1
Bug:
Ik heb de volgende array.
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
[0] => Array
        (
            [id] => 1
            [name] => Appel
            [tooltip] => Klik nu hier
            [link] => index.php/appel/peer/bekijk
            [type] => module
            [parent] => 8
            [menutype] => 1
            [attribs] =>
        )

    [1] => Array
        (
            [id] => 11
            [name] => Appel
            [tooltip] =>
            [link] => appel/peer
            [type] => module
            [parent] => 9
            [menutype] => 1
            [attribs] =>
        )

Ofwel: tooltip heeft in de een een waarde, in de andere is deze NULL.
Nu geeft de class altijd de foutmelding: Invalid property (tooltip) in Nested_Child. Uitcommentariseren van:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
/*if($this->_row === false || !isset($this->_row[$key])) {
            throw new Nested_Exception('Invalid property (' . (string) $key . ') in ' . __CLASS__ . '.');
        }*/

blijkt (voorlopig) de "oplossing".
Roland F
Roland F
19 jaar geleden
 
0 +1 -0 -1
Nou bug wil ik niet zeggen, ik ben bij het programmeren er van uitgegaan dat alle rijen gelijk zijn (alsof ze uit een database komen).

Misschien is dit een betere oplossing;
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
<?php
if($this->_row === false || (!isset($this->_row[$key]) && !is_null($this->_row[$key])) {
    throw new Nested_Exception('Invalid property (' . (string) $key . ') in ' . __CLASS__ . '.');
}

?>
PHP hulp
PHP hulp
0 seconden vanaf nu
 

Gesponsorde koppelingen
Richard van Velzen
Richard van Velzen
19 jaar geleden
 
0 +1 -0 -1
In dat geval kun je beter array_key_exists gebruiken. :-)

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

Inhoudsopgave

  1. php5-array2nested-v112

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.