# Gepost op 15-08-2009 01:43
Bewerkt door vlerknozem op 04-08-2010 18:32
Bewerkt door vlerknozem op 04-08-2010 18:32
Als je iets heb gemaakt in php dat met een database werkt, en vele resultaten op levert, dan kan het handig zijn om deze op te splitsen in meerdere pagina's. Voor mijn forum heb ik een functie geschreven die dit doet. In deze tutorial ga ik proberen uit te leggen hoe het werkt.
1. Uitleg van de SQL
Ik geef een simpel voorbeeld van hoe de sql eruit komt te zien:
De LIMIT zorgt ervoor dat je slechts een bepaald aantal resultaten krijgt. Het eerste cijfer voor de komma zegt vanaf welke row je wilt selecteren. Het tweede cijfer zegt hoeveel resultaten je maximaal wilt opvragen. We hebben zo dadelijk twee querys nodig. Een met deze SQL, en een die het aantal berichten telt.
2. Wat gaan we berekenen?
We moeten een aantal gegevens gaan berekenen. Ten eerste willen we weten hoeveel pagina's er in het totaal moeten komen om alle berichten te weergeven. Dit kan je doen door het aantal berichten te delen door het maximum aantal berichten per pagina. Dit getal ronden we af naar boven. Dat kan met de functie ceil(). Ten tweede willen we weten vanaf welke row de LIMIT moet beginnen. Dit doen we door 1 af te trekken van het huidge pagina nummer, en de uitkomst te vermenigvuldigen met het maximum aantal berichten per pagina. We moeten er 1 van aftrekken omdat we de pagina nummering willen starten vanaf 1, en de limit willen starten vanaf 0.
3. Beginnen met de berekeningen
Eerst gaan we een paar variabelen invullen en wat berekeningen doen:
Ik ga verder niet de query gebruiken, en in een while-lus zetten, in deze tutorial. Ik ga ervan uit dat je dit zelf kan. Als je goed oplet, zie je dat we de variabele $totaal eigenlijk helemaal niet gebruiken! Toch is deze van belang. We gaan hem namelijk zo gebruiken om de urls te maken.
4. De urls maken
Er zijn twee urls die we erg makkelijk kunnen gaan maken. Dit is de url 'Vorige', en de url 'Volgende'. In deze code gebruik ik tevens variabelen die ik in stap 3 heb gemaakt.
Goed, dit is nog redelijk te doen. Als je logisch nadenkt, en niet te lage cijfers hebt/had voor wiskunde, dan zal het ook niet zo moeilijk zijn om te begrijpen. Echter, we willen meer. Er moeten ook nog urls komen met '1,2,3,4,5', etc. Dit gaan we aanpakken in de volgende stap.
5. Tussen urls
De tussen urls maken wordt een lastige stap. Hier vind ik het ook vrij lastig om uitleg te geven. We gaan ook nog wat variabelen erbij maken.
Deze tutorial is gebasseerd op een functie die ik heb geschreven
De volledige code die ik heb gebruikt ga ik ook posten. Deze code is een demonstratie, en er wordt dus geen sql in gebruikt. Ook wijkt het iets af van de tutorial, omdat de tutorial hierop gebasseerd is, en ik de tutorial iets probeerde te verduidelijken. Het is handig om de function te gebruiken, omdat je die voor meerdere doeleindes kan gebruiken. Als je de code hieronder opslaan in een test bestand, kan je er lekker mee experminenteren. Met de uitleg in de tutorial is het niet zo moelijk meer om deze functie in gebruik te nemen met een echte query.
Tot slot
Ik hoop dat deze tutorial duidelijk genoeg is voor jullie. Ik heb bewust gekozen om dit keer geen kant en klare code te plaatsen, omdat het leerzaam is, om het zelf in gebruik te stellen. Mochten er nog fouten in zitten, dan kan je dat altijd melden.
1. Uitleg van de SQL
Ik geef een simpel voorbeeld van hoe de sql eruit komt te zien:
- SELECT * FROM berichten ORDER BY `id` DESC LIMIT 0, 15
De LIMIT zorgt ervoor dat je slechts een bepaald aantal resultaten krijgt. Het eerste cijfer voor de komma zegt vanaf welke row je wilt selecteren. Het tweede cijfer zegt hoeveel resultaten je maximaal wilt opvragen. We hebben zo dadelijk twee querys nodig. Een met deze SQL, en een die het aantal berichten telt.
2. Wat gaan we berekenen?
We moeten een aantal gegevens gaan berekenen. Ten eerste willen we weten hoeveel pagina's er in het totaal moeten komen om alle berichten te weergeven. Dit kan je doen door het aantal berichten te delen door het maximum aantal berichten per pagina. Dit getal ronden we af naar boven. Dat kan met de functie ceil(). Ten tweede willen we weten vanaf welke row de LIMIT moet beginnen. Dit doen we door 1 af te trekken van het huidge pagina nummer, en de uitkomst te vermenigvuldigen met het maximum aantal berichten per pagina. We moeten er 1 van aftrekken omdat we de pagina nummering willen starten vanaf 1, en de limit willen starten vanaf 0.
3. Beginnen met de berekeningen
Eerst gaan we een paar variabelen invullen en wat berekeningen doen:
- <?php
- // Maximaal 15 berichten per pagina
- $max_entries_per_page = 15;
- // Het pagina nummer opvragen uit de url. Als deze niet vermeld is in de url, of dat deze niet nummeriek is, dan gebruiken we de laagste waarde. Dus het cijfer 1.
- // We gaan nu het aantal reacties opvragen uit de database
- // Nu kunnen we berekenen hoeveel pagina's er nodig zijn voor alle reacties.
- // Ook kunnen we erachter komen vanaf welke row we gaan selecteren uit de database.
- $limit = (($pagenum -1) * (int) $max_entries_per_page);
- // En tot slot kunnen we dus de query uitvoeren
- $query = mysql_query("SELECT * FROM `berichten` ORDER BY id DESC LIMIT ". $limit .", ". $max_entries_per_page);
- ?>
Ik ga verder niet de query gebruiken, en in een while-lus zetten, in deze tutorial. Ik ga ervan uit dat je dit zelf kan. Als je goed oplet, zie je dat we de variabele $totaal eigenlijk helemaal niet gebruiken! Toch is deze van belang. We gaan hem namelijk zo gebruiken om de urls te maken.
4. De urls maken
Er zijn twee urls die we erg makkelijk kunnen gaan maken. Dit is de url 'Vorige', en de url 'Volgende'. In deze code gebruik ik tevens variabelen die ik in stap 3 heb gemaakt.
- <?php
- // De url om naar de vorige pagina te gaan. Als het pagina nummer niet groter is dan 1, dan hoeven we ook geen url te maken.
- $url_vorige = ($pagenum > 1) ? '<a href="?page_num='.($pagenum-1).'">Vorige</a>' : 'Vorige';
- // De url om naar de volgende pagina te gaan. Als het totaal aantal berichten groter is dan de huige paginanummer, dan maken we een url. Anders niet.
- $url_volgende = ($pagenum < $totaal) ? '<a href="?page_num='.($pagenum+1).'">Volgende</a>' : 'Volgende';
- ?>
Goed, dit is nog redelijk te doen. Als je logisch nadenkt, en niet te lage cijfers hebt/had voor wiskunde, dan zal het ook niet zo moeilijk zijn om te begrijpen. Echter, we willen meer. Er moeten ook nog urls komen met '1,2,3,4,5', etc. Dit gaan we aanpakken in de volgende stap.
5. Tussen urls
De tussen urls maken wordt een lastige stap. Hier vind ik het ook vrij lastig om uitleg te geven. We gaan ook nog wat variabelen erbij maken.
- <?php
- // Deze variabele bepaald ongeveer hoeveel linkjes er moeten komen. De precieze werking weet ik niet goed uit te leggen, dus daarom stel ik voor dat je met deze variabele
- // eens lekker gaat experimenteren! Zelf vind ik de waarde '3' toch het prettigste.
- $range = 3;
- // Deze bepaald vanaf waar de nummering moet beginnen. In dit geval gebruik ik gewoon de waarde 1.
- $startWith = 1;
- // Deze variabele bepaald of het script gebruik moet maken van de paginanummer in de url. Als je bij mijn forum kijkt onder een subcategorie, dan zie je de topics die
- // in die categorie vallen. De nummering begint daar bij 2 (zie vorige variabele), en deze let niet op de pagina nummer in de url.
- $use_pagenum = true;
- // Deze variabele is de template voor het pagina nummer waar we op dit moment ons bevinden. Deze wordt dan geen url, tenzei dat deze variabele op false staat.
- // De %s wordt vervangen door het pagina nummer
- $current_template = '<b>%s</b>';
- // Het begin van de url, hierna komt de pagina nummer
- $prefix = '?page_num=';
- // Het einde van de url. Niet perse noodzakelijk.
- $suffix = '';
- // De for-lus. Deze is vrij lastig. We lussen vanaf $startWith, tot en met $totaal. De $i houdt bij hoever we zijn.
- for($i = $startWith; $i <= $totaal; $i++) {
- if($i > ($totaal-$range)) {
- # Als de teller ($i) groter is dan het totaal - de range, dan mogen we de dit nummer omzetten tot url
- # Deze if zorgt ervoor dat er geen verdere stappen meer worden ondernomen in deze if-else-structuur
- } elseif($use_pagenum && $totaal > $range && $i > $range && ($i == $pagenum - $range || $i == $pagenum + $range) ) {
- # Als we gebruik maken van het pagina nummer, dan willen we op deze plek die punten plaatsen om de boel te scheiden
- # De preg_replace verwijderd de laatste komma van de string, omdat we deze niet nodig hebben.
- $urls .= '...';
- # Ook zorgen we dat het huidge nummer niet als url wordt opgenomen
- continue;
- } elseif($use_pagenum && $i > ($pagenum - $range) && $i < ($pagenum+$range)) {
- # Eigenlijk zijn dit alle urls in het midden, als we luisteren naar het pagina nummer.
- # 1,2,3...deze dus...65,66,67
- } elseif(!$use_pagenum && $i==($range+1)) {
- # Als we niet luisteren naar de pagina nummer, willen we bij veel resultaten 3 punten in het midden
- $urls .= '...';
- continue;
- } elseif($totaal > $range && $i > $range) {
- # Als het totaal en de teller hoger zijn de de range, willen we voor de rest alles negeren
- continue;
- }
- if($i!=$pagenum || ($i==$pagenum && !$current_template)) {
- // De teller is niet gelijk aan de huidige paginanummer. OF WEL, maar dan is $current_template op de waarde false.
- // Dus we schrijven de url voor pagina nummer $i.
- $urls .= '<a href="'.$prefix.$i.$suffix.'">'.$i.'</a>,';
- } else {
- // Oke, deze pagina wordt op dit moment opgevraagt, en $current_template is niet false.
- // Vervang %s door $i in de 'template'.
- }
- }
- // En weer even de laatste overbodige komma weghalen
- echo $url_vorige .' '. $urls .' '. $url_volgende;
- ?>
Deze tutorial is gebasseerd op een functie die ik heb geschreven
De volledige code die ik heb gebruikt ga ik ook posten. Deze code is een demonstratie, en er wordt dus geen sql in gebruikt. Ook wijkt het iets af van de tutorial, omdat de tutorial hierop gebasseerd is, en ik de tutorial iets probeerde te verduidelijken. Het is handig om de function te gebruiken, omdat je die voor meerdere doeleindes kan gebruiken. Als je de code hieronder opslaan in een test bestand, kan je er lekker mee experminenteren. Met de uitleg in de tutorial is het niet zo moelijk meer om deze functie in gebruik te nemen met een echte query.
- <?php
- function page_num_urls($max, $prefix=null, $suffix=null, $current_template=null, $use_pagenum=true, $startWith=1, $range=3) {
- $prefix = ($prefix!==null) ? $prefix : '?page_num=';
- $suffix = ($suffix!==null) ? $suffix : '';
- $current_template = ($current_template!==null) ? $current_template : false;
- $urls = '';
- for($i = $startWith; $i <= $max; $i++) {
- if($i > ($max-$range)) {
- # Goto Append
- } elseif($use_pagenum && $max > $range && $i > $range && ($i == $pagenum - $range || $i == $pagenum + $range) ) {
- $urls .= '...';
- continue;
- } elseif($use_pagenum && $i > ($pagenum - $range) && $i < ($pagenum+$range)) {
- # Goto Append
- } elseif(!$use_pagenum && $i==($range+1)) {
- $urls .= '...';
- continue;
- } elseif($max > $range && $i > $range) {
- continue;
- }
- // Append
- if($i!=$pagenum || ($i==$pagenum && !$current_template)) {
- $urls .= '<a href="'.$prefix.$i.$suffix.'">'.$i.'</a>,';
- } else {
- }
- }
- return $urls;
- }
- // Alle urls in dit script bevatten &test_reacties en &test_range puur voor de demonstratie. Deze moeten natuurlijk weg als jij het script gebruikt.
- // Ipv daarvan wordt $aantal_reacties gevult m.b.v een query, en $range wordt een config variabele.
- $max_entries_per_page = 15;
- $aantal_reacties = (isset($_GET['test_reacties']) && is_numeric($_GET['test_reacties'])) ? $_GET['test_reacties'] : 1000;
- $tussen_urls = page_num_urls($totaal, null, '&test_reacties='.$aantal_reacties.'&test_range='.$range, '<b>%s</b>', true, 1, $range);
- $limit_x = (($pagenum -1) * (int) $max_entries_per_page);
- $url_vorige = ($pagenum > 1) ? '<a href="?page_num='.($pagenum-1).'&test_reacties='.$aantal_reacties.'&test_range='.$range.'">Vorige</a>' : 'Vorige';
- $url_volgende = ($pagenum < $totaal) ? '<a href="?page_num='.($pagenum+1).'&test_reacties='.$aantal_reacties.'&test_range='.$range.'">Volgende</a>' : 'Volgende';
- echo '(CFG) <b>Range:</b> '.$range.'<br />';
- echo '(CFG) <b>Maximum reacties per pagina:</b> '.$max_entries_per_page.'<br />';
- echo '(URL) <b>Huidige pagina:</b> '.$pagenum.'<br />';
- echo '(SQL) <b>Totaal reacties:</b> '.$aantal_reacties.'<br />';
- echo '(BEREKENING) <b>Totaal paginas:</b> '.$totaal.'<br />';
- echo '(RESULTAAT URLS) <b>Pagina nummers:</b> <small>'. $url_vorige.' '.$tussen_urls.' '.$url_volgende .'</small><br />';
- echo '(RESULTAAT SQL) <b>SQL:</b> LIMIT '. $limit_x .', '.$max_entries_per_page.'<br />';
- ?>
Tot slot
Ik hoop dat deze tutorial duidelijk genoeg is voor jullie. Ik heb bewust gekozen om dit keer geen kant en klare code te plaatsen, omdat het leerzaam is, om het zelf in gebruik te stellen. Mochten er nog fouten in zitten, dan kan je dat altijd melden.
Lees de forum regels