[mysql] Text file naar database structuur

Pagina: 1
Acties:
  • 360 views sinds 30-01-2008
  • Reageer

  • RSD
  • Registratie: Maart 2001
  • Laatst online: 08-02-2017
Ik heb de volgende text file voor een database structuur:

Home
[-]Business & Technology
[-][-]Business Services
[-][-][-]Accounting
[-][-][-][-]Accounting Software
[-][-][-][-]Tax Preparation
[-][-][-]Financial Services
[-]Computers & Electronics

Hoe kan ik dit nu in een database zetten door de text file uit te lezen. Wat is de beste structuur die ik kan gebruiken voor de database? Ik wil dus een php script maken die deze structuur in leest en automatisch een database aanmaakt. Elke categorie krijgt een uniek id en elke categorie moet gekoppeld zijn aan zijn voorganger. Of als er betere oplossingen zijn voor de database ipv aan zijn voorganger te koppelen.

[ Voor 29% gewijzigd door RSD op 21-07-2004 14:26 ]


  • RwD
  • Registratie: Oktober 2000
  • Niet online

RwD

kloonikoon

De beste manier om het in een database te zetten?
Maak gebruik van OmniMark ipv PHP voor de omzetting, ik gebruik het; werkt perfect.

En die dbstructuur in zn simpelste vorm:
ID (Int)
ParentID (Int)
Name (Varchar (255 ofzo))

Maar dan ben je niet helemaal uitgenormaliseerd, want dan komen er misschien nog dingen als het niveau enzo bij. Hiermee kun je makkelijker bepalen hoeveel zo'n categorie moet inspringen bij weergave.

[ Voor 3% gewijzigd door RwD op 21-07-2004 14:29 ]


Verwijderd

Ik vind het altijd nogal vaag als mensen praten over "deze structuur". Wees iets duidelijk met wat je bedoelt.

Waarom wil je dit door een PHP script laten doen? Denk je dat je heel erg veel databases automatisch aan moet gaan maken?

Je hebt totaal niet opgegeven wat voor attributen er horen bij elke entiteit, als het tenminste entiteiten zijn.

En als je vraag in de richting ligt van "hoe parse ik een file", probeer dan eens wat en kom dan terug met te zeggen wat er niet lukt.

Samengevat: de probleemstelling is te vaag om er fatsoenlijk antwoord op te kunnen geven.

[ Voor 6% gewijzigd door Verwijderd op 21-07-2004 14:31 ]


  • RSD
  • Registratie: Maart 2001
  • Laatst online: 08-02-2017
Ik wil het door een php file laten doen omdat ik een beetje kan php scripten. Het is eigenlijk eenmalig voor een shop. Elke categorie bevat produkten. De structuur die ik aangaf is een soort linkstructuur waar mensen straks op kunnen klikken om de produkten te zien. Het is dus voor een website, die geheel wordt opgebouwd uit een database. Nu heb ik een lijstje toegestuurd gekregen van hoe de structuur is. Dit is maar een klein beetje van het complete lijstje. Het origineel bevat ongeveer 1000 categorien, vandaar dat ik het eenmalig in een script wil doen.

Deze ene file zou ik dus willen inlezen en vervolgens moet het scripot van dit lijstje de juiste database creeren met de juiste id's en koppelingen.

[ Voor 12% gewijzigd door RSD op 21-07-2004 14:36 ]


  • RwD
  • Registratie: Oktober 2000
  • Niet online

RwD

kloonikoon

Nou goed, ik snapte al wat je wil doen.

Lees gewoon regel voor regel, kijk hoeveel [-]'s er aan het begin van de regel staan. houd in een array bij welk parent id als laatst zoveel [-]'s - 1 had en dat is je parent...

Misschien niet duidelijk uitgelegd, maar het moet werken denk ik..

Verwijderd

I see. Nou, in dat geval...

Om te beginnen zou ik de [-]'s door 1 symbool vervangen (* ofzo, maakt niet zoveel uit), dan is het aantal straks makkelijk te checken.

Als je dan rij voor rij door de file loopt, controleer je of de huidige rij op gelijke hoogte zit als de vorige (is het aantal *etjes gelijk?).
  • Als dat niet zo is, ga je een niveau dieper. Het ID van de laatste categorie wordt nu het parent-id voor deze en toekomstige categoriën.
  • Als dat wel zo is, dan ga je gewoon lustig verder met het toevoegen van categoriën onder de huidige parent-id.
Vergeet niet dat je de lijst van parent-id's ook weer moet kunnen afwikkelen, dus ze horen op een stack opgeslagen te worden. Je kunt het natuurlijk ook doen met recursieve functie-calls. En het parent-id begint op 0 ofzo, voor de eerste laag die geen ouders heeft.

[edit] Ieks, ik denk te nauw/recursief. RwD's manier is beter :). Hou een tabel bij die aantal sterretjes mapt naar categorie IDs. Zeg, we noemen de tabel $parents, en $ccount is het aantal sterretjes voor het huidige item.

Dan doe je het volgende elke keer als je een rij toevoegt:
PHP:
1
2
3
4
$name = /* ... */;
$parent = $parents[$ccount - 1];
$newid = addToDataBase($parent, $name);
$parents[$ccount] = $newid;


waarbij addToDataBase een functie is die het item toevoegt aan de database en het ID dat het item gekregen heeft teruggeeft.

[ Voor 27% gewijzigd door Verwijderd op 21-07-2004 14:50 ]


  • RSD
  • Registratie: Maart 2001
  • Laatst online: 08-02-2017
Ja maar dat gaat dus niet lukken, want als je dan een categorie hoger gaat, ben je je parent al weer kwijt.

Dus wat gebeurt er bij de laatste 2 rijen in mijn voorbeeld?

[ Voor 24% gewijzigd door RSD op 21-07-2004 14:47 ]


Verwijderd

RSD schreef op 21 juli 2004 @ 14:45:
Ja maar dat gaat dus niet lukken, want als je dan een categorie hoger gaat, ben je je parent al weer kwijt.

Dus wat gebeurt er bij de laatste 2 rijen in mijn voorbeeld?
Daar was de stack dus voor. Maar ik heb mijn post ge-edit, de manier van RwD is makkelijker (dus beter :p).

  • RSD
  • Registratie: Maart 2001
  • Laatst online: 08-02-2017
Bij RwD's manier verlies je het ook volgens mij hoor.. of niet?

Verwijderd

Nee hoor, want op het moment dat je bij "Financial Services" (niveau 3) aankomt is "Business Services" nog altijd de "laatste van niveau 2", en dus wordt deze als parent aangewezen.

[ Voor 14% gewijzigd door Verwijderd op 21-07-2004 14:59 ]


  • RSD
  • Registratie: Maart 2001
  • Laatst online: 08-02-2017
Ja precies, maar "Home" moet juist als parent meegegeven worden. Je stijgt dus 2 nivo's

[ Voor 23% gewijzigd door RSD op 21-07-2004 15:10 ]


Verwijderd

Eh? Toch niet in het voorbeeld wat ik gaf?

[ Voor 5% gewijzigd door Verwijderd op 21-07-2004 15:14 ]


Verwijderd

De leaves vastleggen in de tabel zoals TS zelf aangeeft in zijn tweede post.
Dus werken met een ID, parentID en de rest van je info.

Dan met een recursieve functie uitlezen en weergeven, waarbij je zelf even na zult moeten denken over het in- en uitklappen van de `tree`.

Ik zie niet in waarom je het niet zo kunt doen. Ik zou de levels in ieder geval niet vastleggen in je tabel, aangezien dit later altijd kan wijzigen.
De levels bepaal je door een dynamische variabele in je recursieve functie.

Dan kun je tijdens het genereren aan de hand van het op dat moment huidige level je inspring bepalen etc.

  • RSD
  • Registratie: Maart 2001
  • Laatst online: 08-02-2017
Als we dit als voorbeeld nemen:

Home
[-]Business & Technology
[-][-]Business Services
[-][-][-]Accounting
[-][-][-][-]Accounting Software
[-][-][-][-]Tax Preparation
[-][-][-]Financial Services
[-]Computers & Electronics

De laatste 2 regels, daar ga je van nivo 3 naar nivo 1. Hoe pak je zoiets aan? Dat gaat dus dan niet lukken, of zie ik het nu verkeerd.. bij jullie methode ga je ervan uit dat je alleen maar 1 nivo +/- kan verspringen. Hmmz dat wordt me een beetje te ingewikkeld... recursief... ik weet wat het is, maar in mijn eerste jaar informatica op de uni in Groningen, vond ik dat ook al lastig. Daar ahd je zo een compleet taal voor die alleen maar recursief kon. Maar dat is al weer heeeeeel lang geleden.

[ Voor 45% gewijzigd door RSD op 21-07-2004 15:18 ]


Verwijderd

Mja, in mijn algo werd dat wel enigszins een probleem, maar, nogmaals, in dat van RwD niet, want dat is grotendeels staatloos. Geloof me nou maar, het werkt ècht :p.

Bovendien is dat ook beter dan recursief, want een textbestand moet je toch sequentieel doorlopen.

[ Voor 28% gewijzigd door Verwijderd op 21-07-2004 15:22 ]


  • RSD
  • Registratie: Maart 2001
  • Laatst online: 08-02-2017
Maar die vat ik niet helemaal die van RwD.

En wat kan ik het beste bij de regel van Home zetten als ID en als ParentID ?

PHP:
1
2
3
4
5
6
7
8
9
<?
$handle = fopen("/var/www/html/import/cats.txt", "r");
while (($data = fgets($handle, 10000)) !== FALSE) {
    $ccount = substr_count($data,"*");
    echo $ccount."<br>";
    
}
fclose($handle);
?>


Dit heb ik nu.

[ Voor 111% gewijzigd door RSD op 21-07-2004 15:26 ]


Verwijderd

De code die ik gegeven heb gebruikt het algoritme van RwD en zou "grotendeels" moeten werken. Hij illustreert iig het principe.

En Home kun je in de database zetten en een vast ID geven (bijvoorbeeld 0 of 1), en er dan fysiek categorieën aan verbinden.

Je kan Home ook "virtueel" houden en alle top-level categorieën gewoon als parent-id 0 geven. Of -1. Of welk getal jij "niks" vindt voorstellen.

In allebei de gevallen doe je als initialisatie:

PHP:
1
$parents[0] = 0; // of -1, of het ID van de Home categorie

Verwijderd

Aangezien ik nu toch niks te doen heb... :) :-

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
function addToDatabase($parentid, $name) {
  // Dit werkt, aangenomen dat de ID kolom auto_increment'ing is.
  // Zoniet, dan moet je zelf ff een id aanmaken, en dat later teruggeven.
  $name = addslashes($name);
  mysql_query("INSERT INTO category(parentid, name) VALUES($parentid, \"$name\"");
  return mysql_insert_id();  
}

/* mysql_connect, yada yada... */

$parents[0] = 0;
$lines = file('/var/www/html/import/cats.txt');
foreach ($lines as $line) {
  // Niet erg netjes, voor als de naam misschien een * bevat, maar goed...
  $ccount = substr_count($line, "*");

  $name = substr($line, $ccount);

  if (isset($parents[$ccount - 1])) {

    $parentid = $parents[$ccount - 1];
    $newid = addToDatabase($parentid, $name);
    $parents[$ccount] = $newid;

  } 
  else 
    die("Found an orphan at level $ccount: $name!");
}

[ Voor 47% gewijzigd door Verwijderd op 21-07-2004 15:41 ]


  • RSD
  • Registratie: Maart 2001
  • Laatst online: 08-02-2017
ik zelf had dit al gemaakt, mbv jullie algo's:

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
function addToDatabase ($parent,$name,$id) {
    $newid = $id + 1;
    echo "$newid $parent $name<br>";
    return $newid;
}

echo "ID ParentID Naam<br> ";
$id = 0;
$parents[-1] = 0;
$handle = fopen("/var/www/html/import/cats.txt", "r");
while (($data = fgets($handle, 10000)) !== FALSE) {
    $ccount = substr_count($data,"*");
    $cat_name = str_replace("*","",$data);
    
    $parent = $parents[$ccount - 1]; 
    
    $newid = addToDataBase($parent, $cat_name,$id); 
    
    $parents[$ccount] = $newid;

    $id++;
}
fclose($handle);


Zelfde principe toch? En thanks allemaa, ik denk dat het gelukt is :-)

[ Voor 25% gewijzigd door RSD op 21-07-2004 15:47 ]


Verwijderd

Nog één ding dan: als je uit een file wilt lezen kun je beter file() gebruiken dan fopen()/fgets(). Dat is namelijk sneller en betrouwbaarder.

Overigens heb ik nog een klein foutje gemaakt in mijn code. file() laat namelijk de newlines aan het eind van de regel zitten en daar heb ik geen rekening mee gehouden. De regels moeten dus nog gestrip()t worden :).

  • RSD
  • Registratie: Maart 2001
  • Laatst online: 08-02-2017
Hioj doet het al :-) thnx ...

Nu zoek ik alleen nog iets hoe ik het beste die categorien kan weergeven. Dus een snelle manier om ze op beeld te printen. Ik kan het wel in 5 queries doen. maar dat is zo omslachtig. Dan heb ik 5 queries in 5 while loops ongeveer, ruw gezien. Is daar ook een snelle manier voor?

Verwijderd

Hoe kom jij aan 5 queries? Bedoel je niet O(N^5) queries? :p

In principe kun je de hele bups met 1 query uit je database trekken. Daarna moet je de gegevens in PHP gaan sorteren en uitpoepen.

Bijvoorbeeld, trek alle rijen uit de database, en schrijf ze weg in een array die parentid mapt naar een array van datarijen (die je terug krijgt van mysql_fetch_row of mysql_fetch_object, naar eigen smaak). Oeps, dat was niet heel erg duidelijk...

Het probleem is dat de datastructuur nu een beetje ondoorzichtig begint te worden. PHP gebruikt namelijk Arrays voor alle abstracte datatypes, lijsten, verzamelingen, dictionaries, records, etc. Op een gegeven moment ga je door de Arrays de bedoelde datastructuur niet meer zien.

Ik bedoel een DICTIONARY van parent-id's naar een LIJST van RECORDS. In PHP komt het er op neer dat je 3 array's in elkaar hebt.

Bovendien hou je de rij met Home informatie even apart. Als je dan alles hebt, dan ga je beginnen bij Home en alle items die als parent-id het ID van Home hebben ga je één voor één afbeelden. Maar voor elke categorie daaronder ga je ook alle categorieën die deze weer als parent hebben afbeelden, en zo verder. Nu doe je het dus wel recursief.

Ongeveer zo:

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
/* Let's do the mysql_connect(), yeah */

define("HOME_ID", 1); // Als ik je code goed gelezen heb...

$parentmap = Array();
$home = Array();

// Hier halen we alles uit de database en proppen het in onze eigen
// datastructuur.
$ret = mysql_query("SELECT * FROM category");
while ($row = mysql_fetch_row($ret)) {
  
  // Als het de Home rij is, houden we die apart
  if ($row["id"] == HOME_ID)
    $home = $row;

  // Anders komt hij erbij
  else {
    $pid = $row["parentid"];

    // We voegen hem toe aan de lijst als er al een vorig item was, zoniet
    // dan maken we een nieuwe lijst aan met dit item erin.
    if (isset($parentmap[$pid])) 
      $parentmap[$pid][] = $row;
    else
      $parentmap[$pid] = Array($row);    

  }
}

// Dit is de recursieve functie die de items af gaat beelden
function displayCategory($catrow, $indent) {
  global $parentmap;

  // Toon deze
  echo str_repeat(" ", $indent) . $catrow["name"];

  // Toon kiddo's
  if (isset($parentmap[$catrow["id"]])) 
  foreach ($parentmap[$catrow["id"]] as $subcat) {
    displayCategory($subcat, $indent + 2);
  }
}

// En begin maar met de hoofdcategory. De rest komt daarna vanzelf...
displayCategory($home, 0);

[ Voor 24% gewijzigd door Verwijderd op 21-07-2004 16:28 ]


  • seweso
  • Registratie: Augustus 2003
  • Laatst online: 04-04-2018

seweso

de mouw is uit de aap

Ik durf het bijna niet te zeggen, maar dit soort dingen doe ik meestal in Excel... En dan genereer ik bijvoorbeeld een cvs file of sql commando's. Dat is in veel gevallen sneller dan programmeren....

Maar deze opmerking komt nu misschien ietwat te laat.

seweso's blog


  • Grijze Vos
  • Registratie: December 2002
  • Laatst online: 21-02 23:50
1 tip: gebruik een stack geimplementeerd door een array om de parent te bewaren.

Op zoek naar een nieuwe collega, .NET webdev, voornamelijk productontwikkeling. DM voor meer info


  • RSD
  • Registratie: Maart 2001
  • Laatst online: 08-02-2017
Ik krijg dit als error:

Fatal error: Allowed memory size of 8388608 bytes exhausted (tried to allocate 35 bytes) in /var/www/html/import/printcats.php on line 35

Ik heb ongeveer 800 categorien.. met die O(q^5) zou het helemaal een drama zijn geweest. Terwijl de database maar 30kb groot is.

Ik begrijp het wel, dat stukje code om de categorien af te printen, maar waarom die nu die error geeft?? Is de database te groot ofzoiets? Kan me haast niet voorstellen.

[ Voor 54% gewijzigd door RSD op 21-07-2004 17:13 ]


Verwijderd

8 MB maar? Wat karig! Daar past nog niet eens een Hello World in! :P


Maar ff serieus: op welke regel krijg je de fout? Me dunkt dat er ergens een oneindige lus in zit, want aan de data kan het niet liggen.

  • RSD
  • Registratie: Maart 2001
  • Laatst online: 08-02-2017
op regel 35, in de foreach lus dus... maar wat de fout is??

En als het karig is, dan zal ik de shop binnenkort verhuizen naar een andere server :-)

[ Voor 119% gewijzigd door RSD op 21-07-2004 17:21 ]


  • RSD
  • Registratie: Maart 2001
  • Laatst online: 08-02-2017
Hmm, ik kom er maar niet uit.. iemand misschien suggesties?

Verwijderd

RSD schreef op 21 juli 2004 @ 17:16:
op regel 35, in de foreach lus dus... maar wat de fout is??

En als het karig is, dan zal ik de shop binnenkort verhuizen naar een andere server :-)
"Dus". Al bestaat de enige relevante regel 35 die ik kan zien alleen een comment. Dus. En dat "karig" was maar een grapje.

Ik zou zeggen, sla aan het debuggen. Gewoon naar code staren haalt niet veel uit, en ik zou zo uit mijn blote bolletje niet kunnen zeggen wat het probleem is. Print hier en daar eens wat variabelen uit, kijk wat er in staat, kijk of het probleem zich op een specifiek punt voordoet, etc.

  • RSD
  • Registratie: Maart 2001
  • Laatst online: 08-02-2017
Hehe, ik bedoelde er verder niks mee. Maar die fout zit in de foreach lus, bij mij regel 35. Als ik het script draai, dan geeft hij meteen die error.

Verwijderd

RSD schreef op 21 juli 2004 @ 20:24:
Hehe, ik bedoelde er verder niks mee. Maar die fout zit in de foreach lus, bij mij regel 35.
Ja, en ik heb dus zo geen overzicht van die code. Is dat [precies] dezelfde code als die ik voorgeklopt heb? Zo ja, verwijs er dan naar wat de regel precies is, zo nee, paste dan de code en geef aan om welke regel het draait.
Als ik het script draai, dan geeft hij meteen die error.
:'(

Ja, daarom moet je ook aan 't debuggen slaan. 't Kan goed zijn dat er een fout in mijn code zit, ik ben ook geen guru en je krijgt er geen garanties op. Maar je moet aan 't proberen slaan en proberen de precieze condities waaronder de fout optreedt op te sporen. Als je dat weet, dan is de oplossing in 9 van de 10 gevallen meteen duidelijk. Debuggen is een kunst, maar ook een must.

Overigens wil ik je er op wijzen dat "in de foreach" een recursieve aanroep staat. We hebben hier dus waarschijnlijk met een "stack overflow" te maken, en dat komt in 11 van de 10 gevallen door oneindige recursie. Nu moet je (lees: jij) nog uitzoeken waardoor die optreedt.

  • RSD
  • Registratie: Maart 2001
  • Laatst online: 08-02-2017
ja het is dezelfde code als die jij gebruikt. maar zoals ik al zei.. ik ben geen held in recursief. Ik weet wat het is.. en heb er veel mee geoefend vroeger, maar niet in PHP. Hij geeft die error bij de foreach lus in jouw code.. bij mij is dat regel 35.

Ik heb al naar andere mogelijkheden gezocht, maar die gebruiken ook vaak allemaal recursieve functies.

En als ik het zo bekijk is het ook vrij logisch en begrijp ik het wel. Maar om zelf die recursiviteit te bedenken, dat is vaak het lastigst.

[ Voor 35% gewijzigd door RSD op 21-07-2004 20:39 ]


Verwijderd

Je moet wel een beetje moeite doen je handen vuil te maken he... duik onder de kap van het programma en ga eraan sleutelen. Dat heeft twee voordelen: je leert veel beter hoe het stuk code werkt, en je leert beter programmeren en technieken doorzien. Bovendien leer je hoe je niet-werkende stukken code kunt onderzoeken en fouten kunt opsporen.

Dit leer je alleen door het te doen! (Zoals met alles)

Hier is een eerste tip om te beginnen: Voeg als eerste regel van displayCategory toe:

code:
1
print_r($catrow);


En kijk wat dat oplevert. Als je IE gebruikt, wel eerst View Source doen op de pagina die je dan krijgt, anders wordt het een janboel.

  • RSD
  • Registratie: Maart 2001
  • Laatst online: 08-02-2017
Warning: mysql_connect(): Host 'localhost.localdomain' is blocked because of many connection errors. Unblock with 'mysqladmin flush-hosts' in /var/www/html/import/printcats.php on line 8

Dat geeft ie nu :( Brr.. nu kan ik weer wcahten tot e dat gedaan hebben, zou dit dan ook die ene error geven van 8mb?

Verwijderd

Ja en nee. Die fout komt niet hierdoor, maar dadelijk wel weer. Misschien is het beter de connectie even te closen nadat je de query gedaan hebt, om dit in de toekomst te voorkomen.

[ Voor 20% gewijzigd door Verwijderd op 21-07-2004 20:50 ]


  • RwD
  • Registratie: Oktober 2000
  • Niet online

RwD

kloonikoon

Als alternatief wil je misschien een systeem gebruiken dat niet al je resources opvreet voor een boom waar je het grootste gedeelte niet direct van zult gebruiken. Of heeft iedere gebruiker op ieder moment altijd alle nodes en leaves nodig?

Kijk anders eens naar de Aurigma Deeptree (demo is die structuur links, ook bekend van msdn). Deze werkt uitstekend ook voor grote structuren, en laadt ook alleen de children in van de nodes waar je in geinterresseerd bent.

Ze bieden het alleen aan in asp, maar het asp gedeelte bestaat uit een klein scriptje dat javascript regels moet bouwen per node waar je de children van opvraagt.
- Je stuurt dan een zelf gemaakt php script de id van de huidige node
- Haalt de nodes op met dat id als parent
- Output voor elke node 1 regel javascript zoals je dit ziet in het asp voorbeeld.
- Ga een kopje koffie drinken, goed werk geleverd.
! Probeer in de select query ook meteen op te vragen of de desbetreffende nodes zelf children hebben (of anders dus leaves zijn), dit ziet beter uit in de boom

[ Voor 6% gewijzigd door RwD op 22-07-2004 08:44 ]


  • RSD
  • Registratie: Maart 2001
  • Laatst online: 08-02-2017
Ik heb het nu zo gedaan. Ik heb ergens een script gevonden en deze naar mijn eigen zinnen aangepast. Dit script maakt een navigatie menuutje en laat de categorien zien. Voor de liefhebbers:

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
//make connection hier

function dbfetch ($result){
    if ($row = mysql_fetch_array($result)){
        return $row;
    } else {
        return false;
    }
}

function maketree($rootcatid,$sql,$maxlevel){
    $result = mysql_query($sql);
    while(list($catid,$parcat,$name) = dbfetch($result)){
        $table[$parcat][$catid] = $name;
        $partable[$catid][$parcat] = $name;
    }
    $result = buildparent($rootcatid,$table,$partable,0)."<br>";
    $result .= makebranch($rootcatid,$table,0,$maxlevel);
    return $result;
}

function makebranch($parcat,$table,$level,$maxlevel){
    $list = $table[$parcat];
    if (isset($list)) {
        asort($list);
        while(list($key,$val)=each($list)){
            if ($level == "0"){
                $output = "[img]se.gif[/img]";
            } else {
                $width = ($level+1)*24;
                $output = "[img]e.gif[/img]";
            }
            $result .= "$output <a href=index.php3?catid=$key>$val</a> ($level)<br>\n";
            if ((isset($table[$key])) AND (($maxlevel>$level+1) OR ($maxlevel == "0"))){
                $result .= makebranch($key,$table,$level+1,$maxlevel);
            }
        }
    }
    return $result;
}

function buildparent($catid,$table,$partable,$teller){
    if ($catid != 0 ){
        $list = $partable[$catid];
        $result = each($list);
        if ($teller == 0) {
            $output = "$result[1]";
        } else {
            $output = "<a href=index.php3?catid=$catid>$result[1]</a> / ";
        }
        $output = buildparent($result[0],$table,$partable,$teller+1).$output;
    }
    return $output;
}

if (!isset($catid)){
    $catid = 0;
}

$maxlevel = 0;
print maketree($catid,"SELECT * FROM category",$maxlevel);

[ Voor 16% gewijzigd door RSD op 22-07-2004 09:46 ]


  • RwD
  • Registratie: Oktober 2000
  • Niet online

RwD

kloonikoon

RSD schreef op 22 juli 2004 @ 09:44:
Ik heb het nu zo gedaan. Ik heb ergens een script gevonden en deze naar mijn eigen zinnen aangepast. Dit script maakt een navigatie menuutje en laat de categorien zien. Voor de liefhebbers:

[code...]
Ok, ik herhaal me, maar:

Als ik het goed zie wil je een soort webwinkel achtig iets, in ieder geval waar mensen naar producten kunnen kijken. Dus lijkt het mij persoonlijk een beetje veel om iedere gebruiker altijd alle categorieen te laten zien??

Overigens hoef je niet voor mijn oplossing met de deeptree te gaan, van dit type oplossingen (ik noem ze even druif) kun je een container vol krijgen en je wijnkelder vullen.

Oplossingen en toepassingen voor/van dit soort structuren:
msdn (deeptree)
Nelliesnellen (gebruikt ook die deeptree zo te zien, alleen dan als winkel)
Alternate (ook boomstructuur maar dan anders)
Wehkamp (Mooie toepassing van eenzelfde systeem met andere weergave)
4Images (Forum achtig, ook bruikbaar als webshop na wat modificeren, maar weer een ander soort menu)

(ik kan zo snel niks vinden dat idd ook zoveel categorieen in 1 keer laat zien *schaam*)

Hopelijk help ik hiermee ipv irriteren :*)

[ Voor 8% gewijzigd door RwD op 22-07-2004 10:28 ]


  • RSD
  • Registratie: Maart 2001
  • Laatst online: 08-02-2017
Ik heb nu een database vol met categorien zoals in het begin van dit topic. Echter nu wil ik deze categorien tonen en een navigatie menu erboven hebben. Zodat men altijd weet waar men is. Een beetje amazon achtig. Ik wil geen javascript gebruiken, ivm seo.

Als de gebruiker op mijn site komt, krijgen ze eerst bijv 10 keuzes te zien. Als ze hier op klikken gaan ze een level deep. Het navigatie menuutjehoud bij waar de gebruiker is. Nu worden de subcategorien getoond en de eventuele producten in de hoofdcategorie. Met het script zoals ik het nu doe, wordt de hele databas met categorien ingeladen. Dat is idd een beetje overbodig. Nu heb ik de query wat anders gemaakt:

print maketree($catid,"SELECT * FROM category WHERE ParentID='$catid'",$maxlevel);

Nu werkt de functie makebranch wel, alleen het navigatie menu geeft nu een error.

Echter voor de sitemap wil ik ook van deze functie gebruik maken. Zodat ik met 1 aanroep, een complete sitem,ap kan maken en dat ik kan aangeven van welke categorie ik de submenu's wil laten zien en hoeveel levels deep.

[ Voor 13% gewijzigd door RSD op 22-07-2004 10:43 ]


  • RwD
  • Registratie: Oktober 2000
  • Niet online

RwD

kloonikoon

In principe wil je zoiets als de structuur van dit forum....
Alleen dan geen reacties, maar producten

Snap ik wat je bedoelt?

ps, geen javascript laat deeptree afvallen, maar het alternate menu kan dan wel nog, evenals wehkamps en 4images' menu

[ Voor 33% gewijzigd door RwD op 22-07-2004 10:54 ]


  • RSD
  • Registratie: Maart 2001
  • Laatst online: 08-02-2017
Het liefst dan wehkamp menu.. maar hoe ga ik dat doen.. maar ook het liefst geen dhtml.. gewoon harde html code.

Ik moet eigenlijk een navigatie menu functie hebben en een functie die de subcategorien en producten van een bepaalde categorie ophaalt.

Het navigatiemenu zou dan weer recursief moeten, maar moet ik hiervoor dan ook weer die gehele query doen. Select * from category of kan ik het beste een andere query doen iets van select * from category where catid=parentid

[ Voor 97% gewijzigd door RSD op 22-07-2004 11:09 ]


  • RSD
  • Registratie: Maart 2001
  • Laatst online: 08-02-2017
Dit heb ik nu als navigatie menu:

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
function nav ($catid) {
    if (!isset($catid)){
        $catid = 1;
    }
    
    $sql = "SELECT * FROM category WHERE CatID='$catid'";
    $result = mysql_query($sql);
    while ($row = mysql_fetch_array($result)) {
        $parentid = $row["ParentID"];
        $name = $row["Name"];
        $catid = $row["CatID"];
    }
    $nav = makenav($catid,$parentid,$name,0);
    return $nav;
}

function makenav($subcatid,$subparentid,$subname,$level) {
    if ($subcatid != 0 ) {
        $sql = "SELECT * FROM category WHERE CatID='$subparentid'";
        $result = mysql_query($sql);
        while ($row = mysql_fetch_array($result)) {
            $parentid = $row["ParentID"];
            $catid = $row["CatID"];
            $name = $row["Name"];
        }
        if ($level == 0) {
            $output = "$subname";
        } else {
            $output = "<a href=printcats.php?catid=$subcatid>$subname</a>";
        }
        $output = makenav($catid,$parentid,$name,$level+1)." / ".$output;
    } else {
        $output .= "$name";
    }
    return $output;
}


Aanroepen met nav($catid);

Misschien dat iemand nog suggesties heeft heo het beter/sneller kan?
Pagina: 1