Array rückwärts ab bestimmten Wert durchlaufen

versuch13

Erfahrenes Mitglied
Hallo. Ich möchte gerne ein Array durchlaufen so dass es mir eine Menüstruktur
widergibt. Ich weiß nicht ob das Array dazu vielleicht anders aufgebaut sein müßte.
Das ganze Array zu durchlaufen stellt nicht das Problem dar, sondern das Array
so zu durchlaufen dass es nur den Weg bis zur aktuellen Seite wiedergibt.

So sieht das Array aus, jetzt einfach mal mit ein paar Beispiel Werten:

PHP:
    $nav[0]['id'] = '0';
    $nav[0]['pid'] = '0';
    $nav[0]['uri'] = 'home';
    $nav[0]['link'] = 'Home';
    
    $nav[0]['id'] = '1';
    $nav[0]['pid'] = '0';
    $nav[0]['uri'] = 'ueber_uns';
    $nav[0]['link'] = 'Über uns';
    
    $nav[0]['id'] = '2';
    $nav[0]['pid'] = '1';
    $nav[0]['uri'] = 'das_team';
    $nav[0]['link'] = 'Das Team';
    
    $nav[0]['id'] = '3';
    $nav[0]['pid'] = '2';
    $nav[0]['uri'] = 'der_hans';
    $nav[0]['link'] = 'Der Hans';

Die Werte an denen ich dass gerne steuern würde

PHP:
    $activePage = ';
    $uri = ';


Befindet man sich nun auf der Seite "Home", sollen also nur die Menüpunkte
angezeigt werden deren Wert pid = 0, das wären also

Home
Über uns

PHP:
    $activePage = 'home';
    $uri = 'home';

Bis dorthin ist es ja kein Problem, man liest einfach alle Array Elemente mit pid=0 aus.


Befindet man sich auf der Seite "Über uns", sollte dann sichtbar werden.
Also alles wo pid=0 oder pid=2

Home
Über uns
- Das Team

PHP:
    $activePage = 'das_team';
     $uri = 'ueber_uns/das_team';



Auf der Seite "Das Team"
alle wo pid=0, pid=2 und pid=3

Home
Über uns
- Das Team
-- Der Hans

PHP:
    $activePage = 'der_hans';
    $uri = 'ueber_uns/das_team/der_hans';


Und das wenn möglich bis in unbegrenzte Tiefe auch wenn es nicht benötigt wird,
einfach um es möglich zu machen. Die Daten kommen aus einer MySQL Datenbank,
wenn es notwendig wäre die Daten anders auszulesen, oder bei der Abfrage direkt
in Menüstruktur (ungeordnete Listen) zu bringen wäre das auch möglich. Ich weiß
auch das hier eigentlich nested sets angebracht wären, möchte ich aber wenn
möglich nicht nutzen. Ich hänge auf jeden Fall seit gestern abend daran und komme
einfach nicht weiter.

Am besten fände ich wenn es möglich wäre, sozusagen anhand der variable activePage
das Array so zu durchlaufen dass alle notwendigen Elemente geliefert werden.

Achso, das Ergebnis soll irgendwann mal eine ungeordnete Liste werden um das Menü
darzustellen. Wenn ich jedoch nur ein weiteres Array erhalten würde in dem die notwendigen
Elemente enthalten sind wäre das auch schon ein großer Schritt denke ich.

Vielen Dank im vorraus.
 
Zuletzt bearbeitet:
Ich hab dieses Problem so gelöst:
PHP:
<?php

class Tree{
  var $nodes, $parents, $depth=0;

  function Tree($nodes){
    $this->nodes=$nodes;
    foreach($nodes as $node){
      $parent=$node[2];
      $this->parents[$parent][]=$node[0];
      if (count($this->parents[$parent])>$this->depth){
        $this->depth=count($this->parents[$parent]);
      }
    }
  }

  function get_children($parent, $indent){
    foreach ($this->parents[$parent] as $node){
      $this->prn_child($node,$indent);
      $this->get_children($node,$indent+1);
    }
  }

  function prn_child($node, $indent){

  
for ($in='';$indent>0;$indent--) $in.='&nbsp;&nbsp;&nbsp;';
$in.='x-';
echo("<br>$in$node");
  }
  function get_depth(){
    echo("<br>$this->depth");
  }
}

$sql=array(
array(1,"Root",0),
array(2,"A",1),
array(3,"B",1),
array(4,"C",1),
array(5,"A1",2),
array(6,"B1",3),
array(7,"B2",3),
array(8,"C1",4),
array(9,"A1I",5),
array(10,"C1I",8),
array(11,"C1II",8)
);

$Mytree=new Tree($sql);
$Mytree->get_children(0,1);
$Mytree->get_depth();

?>

Über get_children() lassen sich dann die Unterknoten von einem bestimmten Vater abfragen. Die Einrückung ($indent) ist nur für Darstellungszwecke und kann ggf. weg gelassen werden.
Über get_depth() wird die Tiefe des Baumes ausgegeben.
 
Hey, danke! Das sieht schon mal ganz gut aus. Allerdings verstehe ich es nicht
so ganz und es wird eine Fehlermeldung ausgegeben:

Code:
Warning:  Invalid argument supplied for foreach()

und zwar für diese Zeile
PHP:
foreach ($this->parents[$parent] as $node)

Und ich habe Verständnis Probleme mit der getChildrens Methode, kannst du
mir das bitte etwas erklären?

Danke.
 
Wichtig ist vor allem die foreach-Schleife des Konstruktors:
PHP:
foreach($nodes as $node){
      $parent=$node[2];
      $this->parents[$parent][]=$node[0];
      ...
}
Hier wird ein neues zwei-dimensionales Array $parents befüllt. Der erste Index ist dabei die ID des Vaterelements, der zweite Index die Nummer des Kindes.
Mit get_children() werden sämtliche Kinder zu einem Vater $parent aus dem $parents-Array durchlaufen.
PHP:
foreach ($this->parents[$parent] as $node){...}
Dabei wird zuerst die Ausgabefunktion prn_child jedes Kindes aufgerufen und dann
rekursiv get_children vom Kind selbst, um dessen Kinder zu bestimmen und die Schachtelung der Elemente zu berücksichtigen.
Hat jetzt ein Element keine Kinder mehr, wird natürlich auch kein Array-Eintrag zu diesem Element gefunden, die Rekursion wird beendet und man bekommt eine Warnung, dass es keinen Array-Eintrag gibt, wenn man nicht die Warnungen abgeschaltet hat. Um die Warnungen loszuwerden, kann man die foreach-Schleife in
PHP:
if (isset ($this->parents[$parent])){...}
einbetten.
Für die Ausgabe der eigentlichen Inhalte und nicht der ID solltest Du dann noch das Array $nodes umbauen, so dass du mittels der ID die zugehörigen Inhalte auswählen kannst. Ich hatte es damals noch nicht berücksichtigt, weil es nur ein Test war; aber sicher willst Du ja keine IDs sondern Inhalte ausgeben. ;-)
 
Ok, ich habe mir das jetzt nochmal genauer angesehen und hier wird ja einfach
nur der gesamte Baum durchlaufen, wie gesagt, soweit war ich auch schon.
Das Problem ist ein anderes, und zwar dass ich eben nur bestimmte Zweige
durchlaufen möchte und das ab einer bestimmten Tiefe.

Um das nochmal zu verdeutlichen. Der komplette Baum könnte so aussehen.

Code:
Home
Aktuelles
Über uns
- Das Team
-- Der Hans
--- Interessen vom Hans
Kategorie
- Unter Kategorie 1
- Unter Kategorie 2
Kontakt

Ok, diesen soweit darzustellen ist kein Problem.Das Array ist also aufgebaut wie im
ersten Post kann aber auch verändert werden.

Jetzt möchte ich eine Lösung dafür finden, wie ich zum Beispiel diesen Baum
darstellen kann:

Code:
Home
Aktuelles
Über uns
- Das Team
-- Der Hans
Kategorie
Kontakt

Gegeben wären irgendwelche Merkmale (Zeiger) für -- Der Hans == aktive Seite.

Oder aber zum Beispiel:

Code:
Home
Aktuelles
Über uns
Kategorie
- Unter Kategorie 1
- Unter Kategorie 2
Kontakt

Gegeben wären Merkmale für Kategorie == aktive Seite.


Ich hoffe es ist deutlich wo mein Problem liegt.

Vielen Dank.


Ich bin generell an einer Lösung interessiert auch auf anderem Wege, die Daten
kommen aus einer Datenbank auch die Datenbankstruktur könnte ich verändern.
Es muss nicht unbedingt mit dem Array gearbeitet werden es, hauptsache ist
ich bekomme ein ungeordnete Liste als Ergebnis, also auch an einer Datenbank-
abfrage (MySQL) und Verarbeitung habe ich Interesse. Klar sollte sein, es geht
um die Darstellung einer Menüstruktur anhand der gegeben aktuellen Seite.
 
Zuletzt bearbeitet:
Der Baum wird nur komplett durchlaufen, um das Array umzuformen. (Das neue oder beide Arrays könnte man auch serialisieren und ablegen, dann kann man sich die DB-Abfragen ersparen).
Als Ergebnis hat man dann zwei Arrays:

1. Das Array, in dem zu jedem Element das Elternelement steht (Kind-Vater-Array)
2. Das Array, in dem zu jedem Element die Kinder stehen (Vater-Kinder-Array)

Für Deine Navigation ist folgendes Interessant:
1. Hauptkategorien
2. aktives Element
3. Pfad zum aktiven Element
4. Unterkategorien vom aktiven Element

1.) Die Hauptkategorien sind immer gleich und immer Kindelemente von Root (0) oder Werte des Vater-Kinder-Arrays von [0]

2.) Das aktuelle Element sollte bekannt sein.

3.) Den Pfad zum aktiven Element erhält man, wenn man im Kind-Vater-Array sämtliche Werte, ausgehend vom aktiven Element rekursiv solange durchläuft, bis Vater=0 ist.

4.) Die Unterkategorien sind die Werte des Vater-Kinder-Arrays des aktiven Elementes
 
Mh, ganz ehrlich, ich verstehe kein Wort. Also, ich kann dein Beispiel nur nutzen
um mir den kompletten Baum ausgeben zu lassen, mag sein dass ich was falsch
mache ;) Aber anhand der Aussagen komme ich jetzt leider auch nicht weiter, das
einzige was ich sagen kann, klar das aktive Elemente ist bekannt wie schon im
ersten Beitrag beschrieben. Also wenn du mir da etwas nachhelfen könntest wäre
nett. Danke.
 
Weiß hier niemand Rat? Was ich erreichen möchte wird doch klar oder liegt es eventuell daran? Ist was ich versuche so vielleicht nicht möglich und ich sollte da ganz anders heran gehen?

Danke.
 
Code:
<?php

    $nav[0]['pid'] = '0';
    $nav[0]['uri'] = 'home';
    $nav[0]['link'] = 'Home';
    
    $nav[1]['pid'] = '0';
    $nav[1]['uri'] = 'ueber_uns';
    $nav[1]['link'] = 'Über uns';
    
    $nav[2]['pid'] = '1';
    $nav[2]['uri'] = 'das_team';
    $nav[2]['link'] = 'Das Team';
    
    $nav[3]['pid'] = '2';
    $nav[3]['uri'] = 'der_hans';
    $nav[3]['link'] = 'Der Hans';  

    $nav[3][1]['pid'] = '2';
    $nav[3][1]['uri'] = 'der_hans';
    $nav[3][1]['link'] = 'Der Hans_Unterkategorie';  

?>

Also so würde ich das machen, einfach die Teile direkt per Array anquatschen ;)

[3][1] wäre dann eine Unterkategorie ;)
 
Danke. Wie gesagt wäre es auch möglich das array anders aufzubauen.
Aber das bringt mich ja jetzt in der Darstellung auch nicht weiter.
 
Zurück