[PHP] Paginanavigatie bij nieuwsberichten

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • DragonXZ
  • Registratie: September 2006
  • Laatst online: 10-03 15:29
Goedeavond,

Ik ben bezig met een website met een nieuwssysteem. Echter geeft hij alle nieuwsberichten onder elkaar weer.
Wat ik probeer is bijvoorbeeld 5 berichten per pagina, en dan een navigatiesysteempje eronder. Na twee avonden stoeien is het mij nog steeds niet gelukt.

Mijn nieuws.php:
PHP: filename
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?php
    $sql = mysql_query('SELECT * FROM nieuws ORDER BY nieuws_id DESC');
    if(mysql_num_rows($sql) == 0) {
    echo "Er zijn nog geen nieuws artikels geplaatst.";
    }
    while($row = mysql_fetch_assoc($sql)){

?>

        <h3><?php echo htmlentities($row['titel']); ?></h3>     
        <?php echo nl2br($row['bericht']); ?>
        <p><i>Geschreven door <strong><?php echo $row['naam']; ?></strong> op <strong><?php echo $row['datum']; ?></strong></i></p> 
<div class="bg"></div>

        <?php
        if($row['reageren'] == 'aan') {
                    $sql2 = mysql_query('SELECT * FROM nieuws_reacties WHERE nieuws_id="' . mysql_real_escape_string($row['nieuws_id']) . '"');
                    $count = mysql_num_rows($sql2);
                    $names = str_replace(' ','-','' . $row['titel'] . '');
        ?>
        <a href="<?php echo $siteurl; ?>nieuws/<?php echo $row['nieuws_id']; ?>/<?php echo $names; ?>/">Reacties (<?php echo $count; ?>)


Kan iemand me de goede richting insturen? Alvast bedankt!

Gr.Niels

[ Voor 139% gewijzigd door DragonXZ op 07-09-2010 21:14 . Reden: Code gedit ]


Acties:
  • 0 Henk 'm!

  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 17:46

Creepy

Tactical Espionage Splatterer

Ik heb je totale lap code even weggehaald. Als je code post, post dan aub alleen de relevante code.

Wat heb je nu al precies geprobeerd? Probeer dat eens uit te leggen met de relevante code erbij. Heb je de search hier trouwens al gebruikt? Er zijn vaker topics over geweest waar ook goede uitleg in staat. Gelijk ok even een tikje door naar PRG aangezien het om een implementatie gaat.

[ Voor 11% gewijzigd door Creepy op 07-09-2010 21:14 ]

"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!

  • DragonXZ
  • Registratie: September 2006
  • Laatst online: 10-03 15:29
Excuses, post aangepast.
Ik heb verschillende handleidingen geprobeerd. Deze het meest recent: http://www.sitemasters.be...navigatie_in_PHP_en_MySQL

De code die er nu staat is onaangetast, deze werkt en laat alle berichten zien.

Acties:
  • 0 Henk 'm!

  • moto-moi
  • Registratie: Juli 2001
  • Laatst online: 09-06-2011

moto-moi

Ja, ik haat jou ook :w

Ehm, als ik naar je eerste query kijk, zie ik al niet hoe je daar een subset van je data ophaalt, weet je zeker dat dit de code is die je gebruikt hebt voor paginering? :)

God, root, what is difference? | Talga Vassternich | IBM zuigt


Acties:
  • 0 Henk 'm!

  • DragonXZ
  • Registratie: September 2006
  • Laatst online: 10-03 15:29
Hij haalt nu inderdaad alle nieuwsberichten op. Dat wil ik juist veranderen maar daar kom ik nog niet helemaal uit.

Acties:
  • 0 Henk 'm!

Verwijderd

een goede methode om programmeerproblemen op te lossen is om het uit te schrijven wat je precies wilt, en daarna de code te maken die dit doet.

los het op deze manier op:

1. Kijken hoeveel nieuwberichten je hebt
2. berkenen hoeveel paginas dit worden
3. kijken op welke pagina je je bevindt
4. selecteren van de relevante berichten
5. printen nieuwsberichten
6. printen navagatietje

in simpele code (zelf even uitwerken):
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
//1
$aantal_berichten_per_pagina = 5;

$q = mysql_query("SELECT COUNT(id) as aantal FROM nieuwsberichten");
$aantal = mysql_fetch_assoc( $q ):
$aantal = $aantal['aantal'];
$aantal_paginas = round( $aantal / $aantal_berichten_per_pagina  );

//2 + 3 + 6

$pagina = intval( $_GET['pagina'] );
$pagina == 0 ? $pagina = 1 : "";

$navigatie = "";
$i = 0;
if( $aantal_paginas > 1 ) 
{
    while( $i < $aantal )
    {
        $i++;
        $navigatie .= "<a href='/?pagina=".$i."'>".( $i == $pagina? "<b>" : "" ).$i.( $i == $pagina? "</b>" : "" )."</a>";

    }
}

//4
$start = ( $pagina * $aantal_berichten_per_pagina ) - $aantal_berichten_per_pagina;
$end = $start + $aantal_berichten_per_pagina;

$query = mysql_query("SELECT `bericht`, `datum` FROM `nieuwsberichten` LIMIT ".$start.",".$end."");

//5
while( $r = mysql_fetch_assoc( $query ) )
{
    echo "Bericht ".$r['bericht']." <br/><br/>";
}

//6
echo $navigatie

Acties:
  • 0 Henk 'm!

  • DragonXZ
  • Registratie: September 2006
  • Laatst online: 10-03 15:29
Bedankt voor je berichtje! Kan ik deze code vervangen door mijn huidige plus de query veranderen?

PHP:
1
2
3
<?php 
*snip*
?>


Echter geeft dit een blank resultaat :/

[ Voor 80% gewijzigd door RobIII op 07-09-2010 21:53 ]


Acties:
  • 0 Henk 'm!

  • kluyze
  • Registratie: Augustus 2004
  • Niet online
Verwijderd schreef op dinsdag 07 september 2010 @ 21:33:
een goede methode om programmeerproblemen op te lossen is om het uit te schrijven wat je precies wilt, en daarna de code te maken die dit doet.

los het op deze manier op:

1. Kijken hoeveel nieuwberichten je hebt
2. berkenen hoeveel paginas dit worden
3. kijken op welke pagina je je bevindt
4. selecteren van de relevante berichten
5. printen nieuwsberichten
6. printen navagatietje

in simpele code (zelf even uitwerken):
[...]
2 foutjes in je code

PHP:
18
while( $i < $aantal_paginas ){}
$aantal is het aantal berichten.

en
PHP:
27
28
29
30
$limit_start = ( $pagina * $aantal_berichten_per_pagina ) - $aantal_berichten_per_pagina; 
$limit_aantal = $aantal_berichten_per_pagina; 

$query = mysql_query("SELECT `bericht`, `datum` FROM `nieuwsberichten` LIMIT ".$limit_start.",".$limit_aantal."");
in MySQL heeft LIMIT de syntax start,aantal ipv start,end
[LIMIT {[offset,] row_count | row_count OFFSET offset}]

Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
DragonXZ schreef op dinsdag 07 september 2010 @ 21:50:
Echter geeft dit een blank resultaat :/
Dan begin eens met Debuggen: Hoe doe ik dat?
Op de manier waarop je topic nu loopt wil je het gewoon op een zilveren presenteerschaaltje aangedragen krijgen, en daar doen we hier niet aan (zie ook scriptrequest en Kan iemand even...?). Ik heb (wederom) je code verwijderd. Beperk je tot relevante(!) delen waar je concrete(!) vragen over hebt. Copy/pasten van andermans code/oplossing werkt zelden tot nooit en dan weet je nog steeds niet waar je mee bezig bent en kun je morgen weer een nieuw topic openen omdat het volgende stukje weer niet lukt. Probeer te begrijpen wat er gebeurd en doe daar wat mee.
Give a man a fish and feed him for a day. Teach a man how to fish and feed him for a lifetime.

[ Voor 33% gewijzigd door RobIII op 07-09-2010 21:55 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

  • DragonXZ
  • Registratie: September 2006
  • Laatst online: 10-03 15:29
Het is me gelukt.

Doormiddel van deze tut:
http://www.websiteforum.n...3c93286a99c7ed9e4cb63d58d

Dit toegevoegd aan de code:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<? include('class.navigation.php'); //includeer de class 

$nav = new Navigation($database,'nieuws',2,7); //open de class 

$nav->printout(); //print de navigatie 

$sql = "SELECT * FROM nieuws ORDER BY nieuws_id DESC ".$nav->limit(TRUE); //stel de query op 

$res = mysql_query($sql) or die (mysql_error()); 


    if(mysql_num_rows($res) == 0) {
    echo "Er zijn nog geen nieuws artikels geplaatst.";
    }
    while($row = mysql_fetch_assoc($res)){

?>

Acties:
  • 0 Henk 'm!

  • dB90
  • Registratie: Oktober 2004
  • Laatst online: 03-09 17:28
Snap je nu ook hoe en waarom het werkt?

Webberry Webdevelopment


Acties:
  • 0 Henk 'm!

  • Avalaxy
  • Registratie: Juni 2006
  • Laatst online: 15:43
DragonXZ schreef op dinsdag 07 september 2010 @ 21:11:

PHP: filename
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?php
    $sql = mysql_query('SELECT * FROM nieuws ORDER BY nieuws_id DESC');
    if(mysql_num_rows($sql) == 0) {
    echo "Er zijn nog geen nieuws artikels geplaatst.";
    }
    while($row = mysql_fetch_assoc($sql)){

?>

        <h3><?php echo htmlentities($row['titel']); ?></h3>     
        <?php echo nl2br($row['bericht']); ?>
        <p><i>Geschreven door <strong><?php echo $row['naam']; ?></strong> op <strong><?php echo $row['datum']; ?></strong></i></p> 
<div class="bg"></div>

        <?php
        if($row['reageren'] == 'aan') {
                    $sql2 = mysql_query('SELECT * FROM nieuws_reacties WHERE nieuws_id="' . mysql_real_escape_string($row['nieuws_id']) . '"');
                    $count = mysql_num_rows($sql2);
                    $names = str_replace(' ','-','' . $row['titel'] . '');
        ?>
        <a href="<?php echo $siteurl; ?>nieuws/<?php echo $row['nieuws_id']; ?>/<?php echo $names; ?>/">Reacties (<?php echo $count; ?>)
Mag ik je een aantal tips geven zonder op het initiële probleem in te gaan?
  • Probeer met OOP te leren werken, maakt je code een stuk overzichtelijker :)
  • Je hoeft niet voor elk HTML-wissewasje je PHP te sluiten, je kunt PHP ook gewoon HTML laten printen. Je laatste regel zou dus geschreven kunnen worden als:
    PHP:
    1
    
    <a href="<?= $siteurl . "nieuws/" . {$row['nieuws_id']} . "/" . $names; ?>/">Reacties (<?= $count; ?>)
  • Kan dat dit door je copy-paste komt, maar let ook op je indenting. Na een if doe je meestal een tab (of een aantal spaties) voor alles wat binnen de if zit. Hetzelfde voor loops, methodes, etc.
  • Zet je SQL queries in blokken onder elkaar. Bijvoorbeeld zo:
    PHP:
    1
    2
    3
    
    $sql = mysql_query(' SELECT * 
                                  FROM nieuws 
                                  ORDER BY nieuws_id DESC');

    Sorry, Got verpest m'n indenting, maar de bedoeling is dat FROM direct onder SELECT staat.
    Maakt alles net iets overzichtelijker :)
  • Als je het echt goed aan wilt pakken gebruik je PDO zodat je niet meer met databasespecifieke features zoals de mysql_ functies te maken hebt. Op deze manier kun je makkelijker de transitie doen naar een andere database en hoef je je input niet meer te escapen wanneer je Prepared statements gebruikt.

Acties:
  • 0 Henk 'm!

  • moto-moi
  • Registratie: Juli 2001
  • Laatst online: 09-06-2011

moto-moi

Ja, ik haat jou ook :w

Verwijderd schreef op dinsdag 07 september 2010 @ 21:33:
in simpele code (zelf even uitwerken):
PHP:
1
2
3
4
5
//1
$aantal_berichten_per_pagina = 5;

$q = mysql_query("SELECT COUNT(id) as aantal FROM nieuwsberichten");
$aantal = mysql_fetch_assoc( $q ):
Voor je eerste query zou ik je toch even op http://dev.mysql.com/doc/....html#function_found-rows willen wijzen :)

God, root, what is difference? | Talga Vassternich | IBM zuigt


Acties:
  • 0 Henk 'm!

Verwijderd

@TS
Nee, dit is geen copy/paste code

@kluyze

Tuurlijk staan er foutjes in mn code, als je even op een forum even snel een stukje code uitschrijft gaat dat meestal fout. Het ging er in ieder geval om de TS vooruit te helpen, niet om een copy/paste scriptje neer te zetten.

Jammer dat er dan gekozen wordt voor een compleet script vanaf een of andere website, op die manier leer je het zelf natuurlijk niet, maargoed.

Acties:
  • 0 Henk 'm!

Verwijderd

Thanx, kan inderdaad een stuk effectiever ;-)

Acties:
  • 0 Henk 'm!

  • wackmaniac
  • Registratie: Februari 2004
  • Laatst online: 10:21
Ik weet niet of dat wel sneller gaat zijn, helemaal niet als je gebruik maakt van query cache: http://www.phpdevblog.net...-rows-vs-count-query.html. Als je alleen wilt tellen, wat ik mij kan voorstellen aangezien het ook wel handig is om te kijken wat je totaal aantal pagina's gaat zijn, dan heb je denk ik meer aan COUNT.

Read the code, write the code, be the code!


Acties:
  • 0 Henk 'm!

  • TheLunatic
  • Registratie: April 2001
  • Laatst online: 16-08 21:48

TheLunatic

Ouwe boxen.

Afgezien van je vraag hoor, wat is dit:
PHP:
1
str_replace(' ','-','' . $row['titel'] . '');


Wat doen die '' daar? Ze voegen echt niks toe.

On-topic: waarom niet het aantal berichten limiten met de SQL-optie LIMIT?

code:
1
2
3
SELECT *
FROM nieuwsberichten
LIMIT $pageno*5-5, 5;

Mother, will they like this song?


Acties:
  • 0 Henk 'm!

  • moto-moi
  • Registratie: Juli 2001
  • Laatst online: 09-06-2011

moto-moi

Ja, ik haat jou ook :w

wackmaniac schreef op woensdag 08 september 2010 @ 08:59:
Ik weet niet of dat wel sneller gaat zijn, helemaal niet als je gebruik maakt van query cache: http://www.phpdevblog.net...-rows-vs-count-query.html. Als je alleen wilt tellen, wat ik mij kan voorstellen aangezien het ook wel handig is om te kijken wat je totaal aantal pagina's gaat zijn, dan heb je denk ik meer aan COUNT.
Deze kun je combineren met een gewone select, waarbij hij dus wel alles telt, maar geen extra data over de lijn stuurt daarvoor behalve een eindgetal, hetgeen volgens mij (en die pagina) ook efficiënter is dan een losse count :)

God, root, what is difference? | Talga Vassternich | IBM zuigt


Acties:
  • 0 Henk 'm!

  • wackmaniac
  • Registratie: Februari 2004
  • Laatst online: 10:21
Maar dan moet je alle berichten ophalen, dat is misschien geen overhead als je 2 pagina's hebt, maar wel als je 200 pagina's hebt :) Zend_Paginator had daar eerder ook een handje van; alles ophalen en dan opdelen in pagina's.

Read the code, write the code, be the code!


Acties:
  • 0 Henk 'm!

  • moto-moi
  • Registratie: Juli 2001
  • Laatst online: 09-06-2011

moto-moi

Ja, ik haat jou ook :w

wackmaniac schreef op woensdag 08 september 2010 @ 09:16:
Maar dan moet je alle berichten ophalen, dat is misschien geen overhead als je 2 pagina's hebt, maar wel als je 200 pagina's hebt :) Zend_Paginator had daar eerder ook een handje van; alles ophalen en dan opdelen in pagina's.
Ik denk dat je de uitleg even beter moet lezen :
If you are using SELECT SQL_CALC_FOUND_ROWS, MySQL must calculate how many rows are in the full result set. However, this is faster than running the query again without LIMIT, because the result set need not be sent to the client.

SQL_CALC_FOUND_ROWS and FOUND_ROWS() can be useful in situations when you want to restrict the number of rows that a query returns, but also determine the number of rows in the full result set without running the query again. An example is a Web script that presents a paged display containing links to the pages that show other sections of a search result. Using FOUND_ROWS() enables you to determine how many other pages are needed for the rest of the result.
Voor paginering heb je nou eenmaal een (indicatie) nodig van de hoeveelheid records, daar ontkom je niet aan, en is dit de betere optie dan zelf een count(*) doen imo :)

God, root, what is difference? | Talga Vassternich | IBM zuigt


Acties:
  • 0 Henk 'm!

  • wackmaniac
  • Registratie: Februari 2004
  • Laatst online: 10:21
Beter gelezen; je hebt gelijk. Blijft echter staan dat als je query cache gebruikt op een tabel die veel vaker wordt gelezen dan beschreven COUNT waarschijnlijk sneller gaat zijn.

Read the code, write the code, be the code!


Acties:
  • 0 Henk 'm!

  • Voutloos
  • Registratie: Januari 2002
  • Niet online
COUNT(*) vs CALC_FOUND_ROWS zal je per geval moeten testen, op het moment dat het een bottleneck blijkt. Bij complexe queries met veel joins en filesorts en shit wil CALC_FOUND_ROWS soms opeens idioot traag zijn.

{signature}


Acties:
  • 0 Henk 'm!

  • ReenL
  • Registratie: Augustus 2010
  • Laatst online: 14-09-2022
Je zou eigenlijk op basis van post date moeten sorteren en niet op basis van ID. Zo zou je een post date in de toekomst kunnen doen net als wordpress. Anyway:

Query voor selecteren (waarbij 0 de offset en 5 het aantal resultaten):
PHP:
1
SELECT SQL_CALC_FOUND_ROWS * FROM nieuwsberichten ORDER BY nieuws_id DESC LIMIT 0, 5;


Totaal aantal nieuwsberichten kun je dan zo opvragen:
PHP:
1
SELECT FOUND_ROWS() ;


Hierdoor hoef je niet 2 keer dezelfde query uit te voeren.
Pagina: 1