php-resource




Archiv verlassen und diese Seite im Standarddesign anzeigen :
Baumstruktur


 
Webbi
22-07-2003, 19:33 
 
Moin Moin

Es mag für einige ein langweiliges und altes Thema sein, ich habe hier auch schon einiges gesehen, möchte aber trotzdem mein Problem schildern.

Aus der Datenbank frage ich mit folgendem Script etwas ab:





function checkSite ($SELFPHP, $id, $pid, $blank) {
$result=mysql_query("SELECT * FROM port_menu WHERE id <>'$id' AND pid='$pid' ORDER BY rank");
if(mysql_num_rows($result) > 0) {
$blank = $blank + "1";
while ($row = mysql_fetch_array($result)) {
echo $blank."<a href='".$SELFPHP."?id=".$row[id]."'>".$row[id]."-".$row[pid]."-".$row[name]."-".$row[rank]."</a><br />";
}
}
}

function getMenu ($SELFPHP, $id, $blank) {
$result=mysql_query("SELECT * FROM port_menu WHERE id='$id' ORDER BY rank");
$row = mysql_fetch_array($result);
$s1[] = $blank."<a href='".$SELFPHP."?id=".$row[id]."'>".$row[id]."-".$row[pid]."-".$row[name]."-".$row[rank]."</a><br />";
if($row[pid] != "0") {
$blank = $blank + "1";
getMenu ($SELFPHP, $row[pid], $blank);
}
checkSite ($SELFPHP, $row[id], $row[pid], $blank);
$si = implode("",$s1);
echo $si;
}



Das Script geht rekursiv von der gewählten ID und sucht die parent, bis 0 und gibt alle dazugehörigen untermenus aus.

Das Script an sich läuft, allerdings wird die Reihenfolge überhaupt nicht eingehalten und wenn es Untermenüpunkte gibt diese dann leider auch nicht.

Webbi

Ich hoffe, ich konnte mein Problem gut schildern und danke schon mal.

 
Wotan
22-07-2003, 20:11 
 
hast du dir mal folgenden Thread angesehen:
http://www.php-resource.de/forum/showthread.php?threadid=10351&goto=newpost

 
Webbi
22-07-2003, 20:28 
 
@Wotan: Danke ist an sich ein guter Link.

Ich will nur kein Forum oder sowas.

Hatte nur gedacht, das meine beiden funtionen nur klein sind, dass du oder jemand anders eine idee hat, wo mein fehler sein könnte.

Aber trotzdem danke nochmal

Webbi

 
Konrad
23-07-2003, 12:54 
 
Was willst Du von der ID ermitteln?
Alle Childs?
Alle Parents?

Klär mich noch mal auf... :rolleyes:

 
Wotan
23-07-2003, 13:07 
 
Original geschrieben von Webbi
Ich will nur kein Forum oder sowas.

Die Baumstruktur hat ja nun nichts mit dem Forum oder der Navigation zutun. Der Link sollte dir eigentlich auch nur als Hilfe für deinen Funktionen dienen. Weil dort habe ich/wir(Forum) ja einen rekrusive Abfrage drin. Angefangen vom Parent bis runter ins letzte Child.

Vielleicht schuast du dir ja noch mal den Thread an und vergleichst mal die Funktionen.

 
Webbi
23-07-2003, 14:46 
 
@ Konrad

Also was ich hab ist folgendes:

Das wobinich-script:

1 >> 1.1 >> 1.1.3 >> 1.1.3.1

von 1.1.3.1 hab ich ja die ID!

Mein Script gibt mir auch alle Parents aus, nur total falsch!
Und die Childs bekomme ich nicht!

DIESE wollte ich eigentlich auch dazu benutzen, um meine Menustruktur dazustellen! dabei wird bei dem Menu ein Ranking benutzt.

So soll das eigentlich aussehen!!!
Also wie folgt:

1
1.1
1.1.1
1.1.2
1.1.3
1.1.3.1 //Diesen hab ich gewählt
1.1.3.1.1
1.1.3.1.2
1.1.4
1.2
1.5
1.4
1.3
4
2
3

---------------------------------------
Mein Script gibt aber folgendes aus!

4
2
3
1
1.1
1.2
1.5
1.4
1.3
1.1.1
1.1.2
1.1.3
1.1.4
1.1.3.1 //Diesen hab ich gewählt
Ausgabe der Childs wird nicht ausgegeben!

Ich hoffe ich hab es verständlich gemacht!

@Wotan

Mein Vorhaben ist nicht etwas bisheriges zu nehmen, auch wenn dies eigentlich besser wäre. Ich bräuchte eigentlich nur einen kleinen Denkanstoss (Hilfe) für mein Skript, damit ich das Verständis entlich für dieses bekomme.

Aber trotzdem danke

Webbi

PS: Ich weiss es gibt auch Nested...., allerdings ändern sich vielleich mal öfters die Struktur und wäre damit nicht geeignet und ausserdem müsste ich mich damit noch sehr intensiv beschäftigen.

 
Konrad
23-07-2003, 15:29 
 
Hmm...
Dein 'ORDER BY rank' scheint sich dann wohl auf alle zu beziehen, und nicht nur innerhalb der Gruppen zu greifen.

Ich paste Dir hier mal einen Auszug aus einer Sitemap Klasse, die ich geschrieben habe. Es werden teilweise Objekte benutzt (wie z.B. $db für eine Datanbank Klasse), die musst Du dann halt ersetzen.

Als erstes hole ich mir alle Seiten in ein Array, damit ich nicht bei jedem Aufruf 100+ SQL-Abfragen generiere.

Anmerkung:
Mein root Element (erster Eintrag in der Menütabelle) hat immer die ID 1
Ich sortiere nach parent_id (um erst mal die Gruppen zu bilden) und dann nach Rang.

function get_all(){
global $db;

$strSQL = "SELECT * FROM cms_pages ORDER BY parent_id, rank";
if(!$db->db_com_query("$strSQL")) echo "query failed<BR>".$db->db_com_get_last_error()."<BR>$strSQL<BR>";
while ( $result = $db->db_com_get_next_result() ) {
$this->aryAllPages[$result['cms_pages_id']] = $result;
}
}

jetz habe ich alle Seiten in $obj->aryAllPages mit der ID als Key und allen anderen Werten in einem Array (zweidimensional).

So, hier hole ich mir alle Parents zu einer ID:
function get_all_parents($cms_pages_id){

//----------------------------------------------
// $cms_pages_id wird direkt verwendet
// d.h. die aktuelle Seite erzeugt einen Eintrag
//----------------------------------------------

// solange wir nicht bei 1 (root) oder 0 (ohne Bezug) sind,
// geht es weiter nach oben
//---------------------------------------------------------
while( $cms_pages_id > 1 ){
foreach( $this->aryAllPages as $key=>$aryValue ){
if( $key == $cms_pages_id ){
$aryAllParents[] = $aryValue;

// der Parent wird aktuelle Seite
//-------------------------------
$cms_pages_id = $aryValue['parent_id'];
}
}
}
return($aryAllParents);
}// ende von function get_all_parents

Da wir von 'unten' gekommen sind, müssen wir das Ding noch umdrehen:
$aryHistorie = array_reverse($aryAllParents);

Jetz sollte der ganze Navigationspfad inkl. der aktuellen Seite in der richtigen Reihenfolge in $aryHistorie liegen.

Nun noch den Navipfad über nen foreach laufen lassen und auf Childs prüfen:
function get_all_childs($cms_pages_id){
global $db;

//--------------------------
// gibt es überhaupt Seiten?
//--------------------------
if( count($this->aryAllPages)>0 ){
foreach( $this->aryAllPages as $result ){

//----------------------------------
// wenn unsere Seite ein Parent ist,
// haben wir ein Child gefunden
//----------------------------------
if( $result['parent_id'] == $cms_pages_id ){
$aryAllChilds[] = $result;
}
}
}
return($aryAllChilds);
}

Etwas unstrukturiert das ganze so aus dem Zusammenhang gerissen, aber vielleicht liefert das ja den besagten 'Denkanstoß'. :cool:

 
Webbi
23-07-2003, 15:42 
 
@Konrad

Frage zur Geschwindigkeit:

Geht es nicht ziemlich auf die Geschw., wenn ich alle Muenüpunkte aus der DB hole und erst dann selektiere ? :confused:

Ich würde doch eigentlich meinen, dass es schneller ist, wenn ich wirklich nur die ausgebe, die dazu gehören!

Webbi

PS: Muss jetzt wech ;) Bis später und danke schon mal

 
Konrad
23-07-2003, 15:56 
 
Das ist immer die Gretchenfrage.
Wenn Du nur wenige Menüeinträge hast, hast Du auch wenige SQL-Abfragen oder (wie in meine Fall) ein kleines Array.
Ab welchem Wert ist CPU und RAM besser, als Abfragen auf der Datenbank?
Was liegt von der Datenbank bereits im Speicher?
Muss die Datenbank ein Logfile schreiben?
Wie sieht es aus, wenn mehrere Nutzer gleichzeitig auf die Seite zugreifen?

Bei dem o.a. Sitemapbeispiel habe ich 350+ Menüeinträge auf 4 Ebenen. Bei einem Benchmark mit 5 gleichzeitigen Benutzern und 1000 Anfragen fahre ich mit dem All-Select und den einen Array sehr viel besser, als wenn ich mir die Sitemap mit einzelnen SQL-Abfragen zusammenstelle.

 
Tardan
23-07-2003, 16:13 
 
ich empfehle dir mal bei sowas die Tree classe von pear anzuschaun. sie ist recht konfortabel und arbeitet mit nested trees und somit sehr fix. in über 50% der anwendungs fälle geht es glaube ich nicht schneller für baumstrukturen.
ist auch dokumentiert. habe sie vor wochen selber eingesetzt und bin zufrieden


Alle Zeitangaben in WEZ +2. Es ist jetzt 22:14 Uhr.