geneste pagina's updaten
pagina_id, hoofdpagina_id, naam, url
Nu wil ik dat bij een bepaalde aanroep b.v. update.php?actie=doenu dat de hele boom doorlopen wordt en de url geupdate wordt
Nu heb ik een functie gemaakt (ben daar niet zo heel goed in, maar die doet het volgende)
Code (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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
function updateSEOURL($parent = 0){
$query = mysql_query("SELECT pagina_id, naam, hoofdpagina_id FROM paginas WHERE hoofdpagina_id = '" . $parent . "'");
while($rij = mysql_fetch_assoc($query)){
$huidig_id = $rij['pagina_id'];
$hoofdpagina_id = $rij['hoofdpagina_id'];
$has_sub = '';
$has_sub = mysql_num_rows(mysql_query("SELECT pagina_id, naam FROM paginas WHERE hoofdpagina_id = '" . $huidig_id . "'"));
echo 'BOVEN SELECT pagina_id, naam FROM paginas WHERE hoofdpagina_id = ' . $parent . ' pagina_id ' . $huidig_id . ' naam ' . $rij['naam'] . '<br />';
if($has_sub){
updateSEOURL($huidig_id);
$query_sub = mysql_query("SELECT pagina_id, naam, hoofdpagina_id FROM paginas WHERE hoofdpagina_id = '" . $huidig_id . "'");
while($rij_sub = mysql_fetch_assoc($query_sub)){
echo 'ONDER SELECT pagina_id, naam FROM paginas WHERE hoofdpagina_id = ' . $rij_sub['hoofdpagina_id'] . ' pagina_id ' . $rij_sub['pagina_id'] . ' naam ' . $rij['naam'] . ' subnaam ' . $rij_sub['naam'] . '<br />';
}
}
}
return $html;
}
$query = mysql_query("SELECT pagina_id, naam, hoofdpagina_id FROM paginas WHERE hoofdpagina_id = '" . $parent . "'");
while($rij = mysql_fetch_assoc($query)){
$huidig_id = $rij['pagina_id'];
$hoofdpagina_id = $rij['hoofdpagina_id'];
$has_sub = '';
$has_sub = mysql_num_rows(mysql_query("SELECT pagina_id, naam FROM paginas WHERE hoofdpagina_id = '" . $huidig_id . "'"));
echo 'BOVEN SELECT pagina_id, naam FROM paginas WHERE hoofdpagina_id = ' . $parent . ' pagina_id ' . $huidig_id . ' naam ' . $rij['naam'] . '<br />';
if($has_sub){
updateSEOURL($huidig_id);
$query_sub = mysql_query("SELECT pagina_id, naam, hoofdpagina_id FROM paginas WHERE hoofdpagina_id = '" . $huidig_id . "'");
while($rij_sub = mysql_fetch_assoc($query_sub)){
echo 'ONDER SELECT pagina_id, naam FROM paginas WHERE hoofdpagina_id = ' . $rij_sub['hoofdpagina_id'] . ' pagina_id ' . $rij_sub['pagina_id'] . ' naam ' . $rij['naam'] . ' subnaam ' . $rij_sub['naam'] . '<br />';
}
}
}
return $html;
}
Als ik deze functie aanroep dan krijg ik de volgende ouput:
Code (php)
1
2
3
4
5
6
7
2
3
4
5
6
7
BOVEN SELECT pagina_id, naam FROM paginas WHERE hoofdpagina_id = 0 pagina_id 10 naam home
BOVEN SELECT pagina_id, naam FROM paginas WHERE hoofdpagina_id = 0 pagina_id 1 naam pagina 1
ONDER SELECT pagina_id, naam FROM paginas WHERE hoofdpagina_id = 1 pagina_id 2 naam pagina 1 subnaam pagina 2
BOVEN SELECT pagina_id, naam FROM paginas WHERE hoofdpagina_id = 1 pagina_id 2 naam pagina 2
ONDER SELECT pagina_id, naam FROM paginas WHERE hoofdpagina_id = 2 pagina_id 3 naam pagina 2 subnaam pagina 3
BOVEN SELECT pagina_id, naam FROM paginas WHERE hoofdpagina_id = 2 pagina_id 3 naam pagina 3
BOVEN SELECT pagina_id, naam FROM paginas WHERE hoofdpagina_id = 0 pagina_id 4 naam pagina 4
BOVEN SELECT pagina_id, naam FROM paginas WHERE hoofdpagina_id = 0 pagina_id 1 naam pagina 1
ONDER SELECT pagina_id, naam FROM paginas WHERE hoofdpagina_id = 1 pagina_id 2 naam pagina 1 subnaam pagina 2
BOVEN SELECT pagina_id, naam FROM paginas WHERE hoofdpagina_id = 1 pagina_id 2 naam pagina 2
ONDER SELECT pagina_id, naam FROM paginas WHERE hoofdpagina_id = 2 pagina_id 3 naam pagina 2 subnaam pagina 3
BOVEN SELECT pagina_id, naam FROM paginas WHERE hoofdpagina_id = 2 pagina_id 3 naam pagina 3
BOVEN SELECT pagina_id, naam FROM paginas WHERE hoofdpagina_id = 0 pagina_id 4 naam pagina 4
In principe gaat dit redelijk goed behalve dat ik de entrie die onder "ONDER SELECT" staat niet wil uitvoeren, dan wordt namelijk dezelfde pagina weer overschrven.
Hoe kan ik dus een query maken die alle pagina's/ subpagina's sub- sub pagina's/ sub-sub-sub-sub pagina's een update geeft
Dit type recursie werkt makkelijker als je omhoog werkt van, bij wijze van spreken, achterkleinkind naar overgrootouder. Je controleert nu of een ouder kinderen heeft; draai dat om en controleer of een kind een ouder heeft. Zijn er geen ouders meer, dan ben je op het hoogste niveau in de hiërarchie en eindigt de recursieve verwerking.
Ik heb namelijk nu dit:
UPDATE paginas SET seo_url='home' WHERE pagina_id = '10'
UPDATE paginas SET seo_url='pagina 1' WHERE pagina_id = '1'
UPDATE paginas SET seo_url='pagina 1/pagina 2' WHERE pagina_id = '2'
UPDATE paginas SET seo_url='pagina 4' WHERE pagina_id = '4'
Dit is in principe wat ik mis, behalve dat pagina_id = '2' nog een sub pagina heeft en deze krijg ik nu niet.
Ik doe het nu zo
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
$query = mysql_query("SELECT pagina_id, naam, seo_url, hoofdpagina_id FROM paginas WHERE hoofdpagina_id = '0'");
while($rij = mysql_fetch_assoc($query)){
$query_update = sprintf("UPDATE paginas SET seo_url='%s' WHERE pagina_id = '%s'",
mysql_real_escape_string(strtolower($rij['naam'])),
mysql_real_escape_string($rij['pagina_id'])
);
echo $query_update . '<br />';
#sub query
$query_sub = mysql_query("SELECT pagina_id, naam, seo_url, hoofdpagina_id FROM paginas WHERE hoofdpagina_id = '" . $rij['pagina_id'] . "'");
while($rij_sub = mysql_fetch_assoc($query_sub)){
$query_update_sub = sprintf("UPDATE paginas SET seo_url='%s' WHERE pagina_id = '%s'",
mysql_real_escape_string(strtolower($rij['naam'] . '/' . $rij_sub['naam'])),
mysql_real_escape_string($rij_sub['pagina_id'])
);
echo $query_update_sub . '<br />';
}
}
while($rij = mysql_fetch_assoc($query)){
$query_update = sprintf("UPDATE paginas SET seo_url='%s' WHERE pagina_id = '%s'",
mysql_real_escape_string(strtolower($rij['naam'])),
mysql_real_escape_string($rij['pagina_id'])
);
echo $query_update . '<br />';
#sub query
$query_sub = mysql_query("SELECT pagina_id, naam, seo_url, hoofdpagina_id FROM paginas WHERE hoofdpagina_id = '" . $rij['pagina_id'] . "'");
while($rij_sub = mysql_fetch_assoc($query_sub)){
$query_update_sub = sprintf("UPDATE paginas SET seo_url='%s' WHERE pagina_id = '%s'",
mysql_real_escape_string(strtolower($rij['naam'] . '/' . $rij_sub['naam'])),
mysql_real_escape_string($rij_sub['pagina_id'])
);
echo $query_update_sub . '<br />';
}
}
De sub-sub word nu niet getoond, want ik heb daar geen query voor gemaakt, eigenlijk wil ik dat dit dan netjes in een functie gaat zodat het meteen geupdate wordt en ik dus niet steeds handmatig extra queries moet maken. Hoe kan ik dit in een functie zetten? Dat is eigenlijk mijn doel
Het lijkt er daarom op of je de hiërarchische structuur nog niet perfect genormaliseerd hebt in de database. Kun je de tabel eens posten met toelichting?
Dit is de query die over de lijn gaat:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
$query = "SELECT pagina_id, naam, seo_url, hoofdpagina_id FROM paginas WHERE hoofdpagina_id = '0'";
$resultaat_query = mysql_query($query, $verbindDatabase) or die("A MySQL error has occurred.<br />Your Query: " . $query . "<br /> Error: (" . mysql_errno() . ") " . mysql_error());
while($rij = mysql_fetch_array($resultaat_query)){
$query_update = sprintf("UPDATE paginas SET seo_url='%s' WHERE pagina_id = '%s'",
mysql_real_escape_string(strtolower($rij['naam'])),
mysql_real_escape_string($rij['pagina_id'])
);
echo $query_update . '<br />';
updateSEOURL($rij['pagina_id'], strtolower($rij['naam']));
}
$resultaat_query = mysql_query($query, $verbindDatabase) or die("A MySQL error has occurred.<br />Your Query: " . $query . "<br /> Error: (" . mysql_errno() . ") " . mysql_error());
while($rij = mysql_fetch_array($resultaat_query)){
$query_update = sprintf("UPDATE paginas SET seo_url='%s' WHERE pagina_id = '%s'",
mysql_real_escape_string(strtolower($rij['naam'])),
mysql_real_escape_string($rij['pagina_id'])
);
echo $query_update . '<br />';
updateSEOURL($rij['pagina_id'], strtolower($rij['naam']));
}
Dit is de functie:
Code (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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
function updateSEOURL($pagina_id = 0, $naam = ''){
global $verbindDatabase;
#sub query
$query_sub = "SELECT pagina_id, naam, seo_url, hoofdpagina_id FROM paginas WHERE hoofdpagina_id = '" . $pagina_id . "'";
$resultaat_query_sub = mysql_query($query_sub, $verbindDatabase) or die("A MySQL error has occurred.<br />Your Query: " . $query_sub . "<br /> Error: (" . mysql_errno() . ") " . mysql_error());
$aantal_query_sub = mysql_num_rows($resultaat_query_sub);
if($aantal_query_sub > 0){
//updateSEOURL($rij_sub['pagina_id'], $rij['naam']);
while($rij_sub = mysql_fetch_array($resultaat_query_sub)){
$query_update_sub = sprintf("UPDATE paginas SET seo_url='%s' WHERE pagina_id = '%s'",
mysql_real_escape_string(strtolower($naam . '/' . $rij_sub['naam'])),
mysql_real_escape_string($rij_sub['pagina_id'])
);
echo $query_update_sub . '<br />';
updateSEOURL($rij_sub['pagina_id'], strtolower($naam . '/' . $rij_sub['naam']));
}
}
}
global $verbindDatabase;
#sub query
$query_sub = "SELECT pagina_id, naam, seo_url, hoofdpagina_id FROM paginas WHERE hoofdpagina_id = '" . $pagina_id . "'";
$resultaat_query_sub = mysql_query($query_sub, $verbindDatabase) or die("A MySQL error has occurred.<br />Your Query: " . $query_sub . "<br /> Error: (" . mysql_errno() . ") " . mysql_error());
$aantal_query_sub = mysql_num_rows($resultaat_query_sub);
if($aantal_query_sub > 0){
//updateSEOURL($rij_sub['pagina_id'], $rij['naam']);
while($rij_sub = mysql_fetch_array($resultaat_query_sub)){
$query_update_sub = sprintf("UPDATE paginas SET seo_url='%s' WHERE pagina_id = '%s'",
mysql_real_escape_string(strtolower($naam . '/' . $rij_sub['naam'])),
mysql_real_escape_string($rij_sub['pagina_id'])
);
echo $query_update_sub . '<br />';
updateSEOURL($rij_sub['pagina_id'], strtolower($naam . '/' . $rij_sub['naam']));
}
}
}
En dit is de output:
Code (php)
1
2
3
4
5
2
3
4
5
UPDATE paginas SET seo_url='home' WHERE pagina_id = '10'
UPDATE paginas SET seo_url='pagina 1' WHERE pagina_id = '1'
UPDATE paginas SET seo_url='pagina 1/pagina 2' WHERE pagina_id = '2'
UPDATE paginas SET seo_url='pagina 1/pagina 2/pagina 3' WHERE pagina_id = '3'
UPDATE paginas SET seo_url='pagina 4' WHERE pagina_id = '4'
UPDATE paginas SET seo_url='pagina 1' WHERE pagina_id = '1'
UPDATE paginas SET seo_url='pagina 1/pagina 2' WHERE pagina_id = '2'
UPDATE paginas SET seo_url='pagina 1/pagina 2/pagina 3' WHERE pagina_id = '3'
UPDATE paginas SET seo_url='pagina 4' WHERE pagina_id = '4'
Pagina 1 = hoofdpagina
Pagina 2 = subpagina van pagina 1
Pagina 3 = subpagina van pagina 2
Volgens mij klopt dit zo wel?
Let even niet op dat strtolower voor de seo url, daar ga ik nog iets mee doen, speciale tekens eruit, spaties vervangen door - etc.
Dit is de bijbehorende database:
Gewijzigd op 12/10/2012 14:26:36 door Pong Zor
SET seo_url='pagina 1/pagina 2/pagina 3' WHERE pagina_id = '3'
De string 'pagina 1/pagina 2/' wordt namelijk bepaald door de bovenliggende pagina's met pagina-id 1 en 2, niet door pagina 3 zelf. Je probeert nu al zoekend overal het gedeelte 'pagina 2/' te vervangen, maar dat kan met één update van pagina 2 zelf.
Maar hoe moet ik het dan doen? Ik ben je nu even kwijtgeraakt denk ik, want die url is juist wel de URL die ik wil hebben
1 http://www.example.com/fruit/
2 http://www.example.com/fruit/appelen/
3 http://www.example.com/fruit/appelen/elstar.html
4 http://www.example.com/fruit/appelen/golden-delicious.html
5 http://www.example.com/fruit/appelen/jonagold.html
Als je nu /appelen/ wilt vervangen door /appels/, zou dat één UPDATE moeten zijn van de pagina 2. Alle pagina's lager in het pad (hier 3 t/m 5) overerven dan de wijziging:
1 http://www.example.com/fruit/
2 http://www.example.com/fruit/appels/
3 http://www.example.com/fruit/appels/elstar.html
4 http://www.example.com/fruit/appels/golden-delicious.html
5 http://www.example.com/fruit/appels/jonagold.html
Je slaat hiervoor niet de volledige SEO-URL per pagina op, maar alleen het gedeelte dat per pagina uniek uniek is. Dat je nu meerdere query's moet uitvoeren, is een teken dat je database herhaalde en redundante data bevat. Normaliseren dus.
Gewijzigd op 12/10/2012 14:49:15 door Ward van der Put
Toevoeging op 12/10/2012 14:52:55:
In principe zou ik pagina 3 gewoon seo url pagina-3 kunnen laten hebben en dan vervolgens met een query de url opbouwen
b.v. SELECT seo_url FROM paginas WHERE hoofdpagina='0' en dan het hele riedeltje door gaan. Dan kom ik op het volgende punt mijn .htaccess
RewriteRule ^([0-9]+)/(.*)/$ index.php?pagina_id=$1&seo_url=$2
Die pakt het ID van de pagina en de bijbehorende SEO URL op. In dat geval zou het b.v. /3/pagina-3 worden. Dan mis ik dus pagina-1/pagina-2/pagina-3
Voor de recursie hoef je per pagina alléén te weten wat de bovenliggende pagina is. Bijvoorbeeld de elstar.html rubriceer je onder appels, niet een niveau hoger onder fruit en (bewijs) al helemaal niet onder het hoogste niveau home. In je database zou hoofdpagina_id niet moeten verwijzen naar het hoogste niveau, maar naar het bovenliggende niveau: het is meer een ouder_id of parent_id.
Pagina 3 verwijst naar bovenliggende pagina 2.
Pagina 2 verwijst naar bovenliggende pagina 1.
Hoofdpagina met een id van 0 geeft aan dat het hier om het hoogste niveau gaat.
Zie: http://mikehillyer.com/articles/managing-hierarchical-data-in-mysql/
Een manier om met mySQL gegevens in een hierarchie te steken; in een boomstructuur, zo breed, diep en genest als je wil.
Het geeft je een set uitgewerkte query's waarmee je een hele tak kan aanspreken; een tak kan verwijderen, een hele tak kan verplaatsen naar een andere tak, ...
Alles wat relevant is voor een boomstructuur.
Maar laat me wel even waarschuwen dat je wat tijd en oefening nodig hebt om dit onder de knie te krijgen. De kans is vrij reëel dat het de moeite niet waard is, als je al met een bestaande toestand zit.
Klopt, maar dat is nu juist het voordeel. Je hoeft niet meer te weten dan: dit is elstar.html. Daarna kun je uit de ouder_id in de database afleiden dat deze pagina onder /appels/elstar.html staat. Vervolgens weet je via de ouder /appels/ dat de grootouder het deel /fruit/ in het complete pad /fruit/appels/elstar.html moet zijn.
Want die krijgt dan in de browser deze url terug:
domein.nl/3/pagina1/pagina2/pagina3
maar vervolgens is de url dan:
domein.nl/index.php?pagina_id=3&seo_url=pagina3
Dit komt niet meer overeen en dus krijg ik een foutmelding: