[PHP / MySQL] Properties opvragen van tree nodes

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Reveller
  • Registratie: Augustus 2002
  • Laatst online: 05-12-2022
Ik heb een kind-ouder tabel met o.a. de volgende nodes:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
+-----+-----+-------+-------+--------+
| nid | pid | title | alias | type   |
+-----+-----+-------+-------+--------+
| 1   | 0   | Home  |       | home   |
+-----+-----+-------+-------+--------+
| 142 | 1   | Vlees | vlees | story  |
+-----+-----+-------+-------+--------+
| 144 | 1   | Fruit | fruit | story  |
+-----+-----+-------+-------+--------+
| 149 | 142 | Rood  | rood  | store  |
+-----+-----+-------+-------+--------+
| 150 | 144 | Rood  | rood  | book   |
+-----+-----+-------+-------+--------+
Mijn CMS'je werkt met vriendelijke URL's. Stel een bezoeker die surft naar http://site.com/vlees/rood/. Ik wil er zeker van zijn dat ik de goede pagina 'rood' pak. Rood vlees (nid=149) in dit geval, niet rood fruit (nid=150). Ik controleer dat door de querystring (vlees/rood) naar een array te exploden en dynamisch een query op te bouwen die de goede nid retourneert:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function getActiveItem($pad)
{ 
  $join = '';
  $and  = '';
  
  $i = count($pad);

  for ($j = 0; $j < $i; $j++)
  {
    $join .= 'INNER JOIN nodes n'.($j+2).' ON n'.($j+1).'.nid = n'.($j+2).'.pid ';
    $and  .= ' AND n'.($j+2).'.alias = "'.$pad[$j].'"';
  } 

  $result = db_query('SELECT n'.($i+1).'.nid FROM nodes n1 '.$join.'WHERE n1.pid = 0'.$and.' LIMIT 1');
  
  if (db_num_rows($result) == 1)
  {
    return (db_result($result, 0));
  }
}

In het gekozen voorbeeld zou de query als volgt zijn. Ik krijg dan idd keurig "149" terug van mysql:
code:
1
2
3
4
5
SELECT n3.nid FROM nodes n1 
INNER JOIN nodes n2 ON n1.nid = n2.pid 
INNER JOIN nodes n3 ON n2.nid = n3.pid 
WHERE n1.pid = 0 AND n2.alias = "vlees" 
AND n3.alias = "rood" LIMIT 1

Ik wil nu deze functie uitbreiden / een tweede functie schrijven zodat ik de properties terugkrijg van alle nodes die leiden tot de huidige pagina. Met andere woorden, iets als:
code:
1
2
3
4
5
6
7
8
$querystring[0]['nid']   = 142
$querystring[0]['pid']   = 1
$querystring[0]['alias'] = vlees
$querystring[0]['type']  = story
$querystring[1]['nid']   = 149
$querystring[1]['pid']   = 142
$querystring[1]['alias'] = rood
$querystring[1]['type']  = store
Ik heb alleen geen idee hoe ik dit moet aanpakken. Graag hoor ik jullie tips over:
• of ik een nieuwe functie moet schrijven of deze aan kan passen
• of dit met 1 query kan en zo ja; hoe deze eruit zou moeten zien. Mijn sql kennis is hiervoor nog niet groot genoeg. Het schrijven van de huidige functie kostte me veel moeite; ik hoop een duwtje in de goede richting te krijgen over de uitbreiding ervan :)

[ Voor 8% gewijzigd door Reveller op 01-01-2005 19:22 ]

"Real software engineers work from 9 to 5, because that is the way the job is described in the formal spec. Working late would feel like using an undocumented external procedure."


Acties:
  • 0 Henk 'm!

  • Creepy
  • Registratie: Juni 2001
  • Nu online

Creepy

Tactical Espionage Splatterer

Je vraagt het NID al op, dus in je select de velden uitbreiden lijkt me geen probleem? Vervolgens vul je een 2 dimensionale array met de opgevraagde waarden en gaan. Ik zie hier echt het probleem niet in? (wel de LIMIT weghalen)

Je functie getActiveItem gebruikt DB functies (db_query) die niet standaard van PHP zijn. Dus het kan zijn dat je misschien die functies ook nog moet aanpassen.

Wat heb je nu zelf al geprobeerd? En wat lukt daar niet mee? Het is een kleine moeite en vrij simpel om vanuit wat je nu hebt de voel uit te breiden om een array terug te krijgen met de info die jij wilt.

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


Acties:
  • 0 Henk 'm!

  • Reveller
  • Registratie: Augustus 2002
  • Laatst online: 05-12-2022
@Creepy - wat jij zegt heb ik al eerder geprobeerd. Ik had regel 14 veranderd in
PHP:
1
  $result = db_query('SELECT n'.($i+1).'.nid, n'.($i+1).'.type FROM nodes n1 '.$join.'WHERE n1.pid = 0'.$and);

Ik krijg dan idd een array terug met de nid en type van "rood", maar niet van "vlees". De bedoeling is om van alle node (van root tot aan de gevraagde pagina) deze properties op te halen, en dat lukt me niet. Overigens is db_query niets bijzonders: deze functie sprintf de variabelen en retourneert een mysql_query() resulaat.

UPDATE: als ik de volgende query run
code:
1
2
3
4
5
SELECT n2.nid, n2.type, n3.nid, n3.type
FROM nodes n1
INNER  JOIN nodes n2 ON n1.nid = n2.pid
INNER  JOIN nodes n3 ON n2.nid = n3.pid
WHERE n1.pid =0 AND n2.alias =  "vlees" AND n3.alias =  "rood"

retourneert mysql:
code:
1
2
3
4
5
+-----+-------+-----+-------+
| nid | type  | nid | type  |
+-----+-------+-----+-------+
| 142 | story | 149 | store |
+-----+-------+-----+-------+

De vraag die nu nog rest is of deze query ook vereenvoudigd kan worden?

[ Voor 37% gewijzigd door Reveller op 01-01-2005 22:16 ]

"Real software engineers work from 9 to 5, because that is the way the job is described in the formal spec. Working late would feel like using an undocumented external procedure."