Denkblockade zu rekursiven Funktionen

Hallo Experten,

irgendwie hab ich glaub ich eine denkblockade zu folgendem Problem…
Ich möchte je nachdem, wie eine Variable gesetzt ist eine rekursive Funktion aufbauen, die mir ein Navigationsmenü aus einer mysql-Datenbank erstellt…

dazu hatte ich an folgendes System gedacht

funktionsname(0);

function ($wert)
{
select where ref\_id=$wert
while fetch array
 {
 echo $row[titel]
 funktionsname($row[id]);
 }
}
also eine relativ einfache verkettung bei der die oberste Ebene mit ref\_id=0 gekennzeichnet wird und sich untergeordnete Elemente auf die auto\_incrent id beziehen...
Nun möchte ich es aber auch so angehen können, dass nicht alle Zweige des Navigationssystems angezeigt werden, sondern nur der angeklickte Zweig sich ausfährt sprich eine Art Ordnerstruktur (Baum) wie man es aus dem Dateiexplorer kennt...
nur irgendwie weiss ich grade nicht wie ich das angehen soll...

Hi,

Du kannst natürlich die ref_id’s codieren, d.h.:
name id ref_id

home 1 0
links 2 0
extern 21 2
intern 22 2
lustiges 211 21

dann in php:
function ($wert,$click)
{
select where ref_id=$wert
while fetch array
{
echo $row[titel]
if (substr($click,0,strlen($wert))==$wert)
{
funktionsname($row[id]);
}
}
}

Nachteil: wenn du einen Teilbaum verschieben willst, ist das mit sehr viel Aufwand verbunden.

ich arbeite noch an einer anderen methode…

bis dann,

Omar Abo-Namous

http://www.islaminhannover.de

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

Ok, here goes nothing!!

function ($wert,$node)
{
global $click;
select where ref_id=$wert
$data="";
$occured=0;
$oldoccured=0;
while fetch array
{
$data.=$row[titel];
if ($row[titel]==$click)
{
$occured=1;
}
if ($node==0)
{
list($newdata,$newoccured)=funktionsname($row[id],$occured);
if ($newoccured==1)
{
$data.=$newdata;
}
}
if ($oldoccured==1 || $occured==1 || $newoccured==1)
{
$oldoccured=1;
}
$occured=0;
}
return array($data,$oldoccured);
}

probier mal aus und sag bescheid. Aufrufen tust du das hiermit:

$click=3; (das ist die id, nach der du suchst)
function (0,0);

Fragen?

Omar Abo-Namous

http://www.islaminhannover.de

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

1 Like

danke schon mal
ich muss das noch ein wenig durchdenken, was du da genau machst und welche Tabellenstruktur ich da nun brauche…
hoffe mal ich kriegs hin… is nur jetzt bissl zu spät um da nen klaren Kopf zu haben *g*
*morgen schon mal einplan das durchzudenken* ;=)

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

hui wow…
das Ding hats echt in sich… aber vielleicht sag ich das auch nur, weil ich es immernoch nicht verstehe *ggg*

kannst Du mir mal noch ein wenig helfen?
mal angepasst und kommentiert was ich so verstehe…

function rec($wert,$node)
 {
 global $tblnavi, $click;
 $query = mysql\_query("select \* FROM $tblnavi where ref\_id=$wert"); //Daten werden geholt (erstaufruf = oberste Ebene)
 $data=""; //data wird geleert??? warum?
 $occured=0;
 $oldoccured=0;
 while ($row = mysql\_fetch\_array($query)) //die ergebnisse werden einzeln durchgearbeitet
 {
 $data.=$row[titel]."
"; //data wird belegt mit dem Titel des DB eintrags...
 if ($row[id]==$click) //wenn die id mit dem "click" übereinstimmt....
 {
 $occured=1; //wird das mal auf 1 gesetzt (wird unten geprüft)
 }
 if ($node==0) //wenn es nicht aufgetreten ist wird die schleife ausgeführt...
 {
 list($newdata,$newoccured)=rec($row[id],$occured); //...die die Variablen newdata und newoccured für unten belegt mit den resultaten, die die Funktion selbst zurückliefert. Dabei werden alle untergeordneten Beiträge geprüft, ob dort $click übereinstimmt und dieser Zweig angezeigt werden soll
 if ($newoccured==1) //wenn ja
 {
 $data.=$newdata."
"; //wird hier der neue $data-Wert belegt...
 }
 }
 if ($oldoccured==1 || $occured==1 || $newoccured==1) //wenn eines davon auf 1 gesetzt wird soll das behalten werden
 {
 $oldoccured=1; //weswegen der oldoccured wert auf 1 gesetzt wird
 }
 $occured=0; //warum das denn?
 }
 return array($data,$oldoccured);
 }

$oldoccured kann glaub ich beim letzten if nicht 1 sein, weil er nur danach gesetzt wird wenn ich das richtig sehe…
Nun aber noch ein kleines weiteres Problem - $click ist ja normalerweise nicht belegt und soll dann ja die ganzen untergeordneten Zweige auch noch öffnen…
also ein

eins
zwei
drei

soll bei klick auf zwei dann so aus sehen:

eins
zwei
 a;
 b;
 c;
drei

das funktioniert so noch nicht… Ich denke mal, dass ich da dann eine Funktion einfüge, die dann aufgerufen wird, wenn §click = $row[id] ist, oder wie würdest Du das lösen?

Jedenfalls schon mal ein sternchen für diese Lösung… Danke!!

solved
to whom it may concern:
source code:

function navi($wert,$node)
 {
 global $tblnavi, $click;
 $query = mysql\_query("select \* FROM $tblnavi where ref\_id=$wert"); 
 $data=""; 
 $occured=0;
 $oldoccured=0;
 while ($row = mysql\_fetch\_array($query)) 
 {
 $data.=$row[titel]."
"; 
 if ($row[id]==$click) 
 {
 $occured=1; 
 $query2=mysql\_query("SELECT \* FROM $tblnavi WHERE ref\_id=$row[id]");
 while ($result=mysql\_fetch\_array($query2))
 {
 $data .= $result[titel]";
 } 
 }
 if ($node==0)
 {
 list($newdata,$newoccured)=navi($row[id],$occured); 
 if ($newoccured==1)
 {
 $data.=$newdata; 
 }
 }
 if ($oldoccured==1 || $occured==1 || $newoccured==1) 
 {
 $oldoccured=1; 
 }
 $occured=0;
 }
 return array($data,$oldoccured);
 }

jetzt muss ich nur noch sehen, ob ich realisieren kann, jedesmal die Ebene der durchführung anzeigen zu lassen um evtl einrücken zu können *g*

auch das gelöst *g*

jetzt muss ich nur noch sehen, ob ich realisieren kann,
jedesmal die Ebene der durchführung anzeigen zu lassen um evtl
einrücken zu können *g*

den source code erspare ich euch mal - war simpel :wink:

Also zunächst einmal oldoccured wird ja in einer schleige gesetzt, deshalb kann es sehr wohl 1 sein.

Dann hast du aber jetzt ein „Doppelgemoppen“! Die Variable $node ist 1, wenn der Mutterzweig schon ==$click ist. Deine Lösung mit der kleineren while-schleife ist hübscher (nicht gerade rekursiv korrekt, aber wen interessiert das?) aber ich würde dann an deiner Stelle $node komplett weglassen:

if ($row[id]==$click)
{
$occured=1;
$query2=mysql_query(„SELECT * FROM $tblnavi WHERE
ref_id=$row[id]“);
while ($result=mysql_fetch_array($query2))
{
$data .= $result[titel]";
}
}
else
{
list($newdata,$newoccured)=navi($row[id]);
if ($newoccured==1)
{
$data.=$newdata;
}
}

natürlich musst du auch im Funktionsaufruf $node weglassen:
function navi($wert)

bis denne,

Omar Abo-Namous

http://www.islaminhannover.de

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]