pagination laat bij een zoek opdracht maar 1 pagina zien

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Klaas Buskes

Klaas Buskes

29/01/2018 20:25:16
Quote Anchor link
Hoi Iedereen,

Na mijn vorige probleempje, dat met jullie hulp, tot een goed einde is gekomen stuit ik op een nieuw vraagstuk.

In mijn database heb ik een script gevonden om data 'paginated' weer te geven met 10 resultaten per pagina.

Als ik dit zelfde script gebruik om data weer te geven na een zoek opdracht krijg ik maar 1 pagina te zien.

Code (php)
PHP script in nieuw venster Selecteer het PHP script
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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
<?php

include('db.php');

$per_page = 10;        // aantal resultaten per pagina

if ($result = $con->query("SELECT * FROM strips ORDER BY id")) {
    if ($result->num_rows != 0) {        
        $total_results = $result->num_rows;  
        $total_pages = ceil($total_results / $per_page);  
    
        if (isset($_GET['page']) && is_numeric($_GET['page'])) {    
            $show_page = $_GET['page'];

            if ($show_page > 0 && $show_page <= $total_pages) {
                $start = ($show_page -1) * $per_page;
                $end = $start + $per_page;
            }
else {
                $start = 0;
                $end = $per_page;
            }
        }
else {
            $start = 0;
            $end = $per_page;
        }


// laat de resultaten zien

        echo "<p> <b>Bekijk pagina:</b> ";
        for ($i = 1; $i <= $total_pages; $i++) {
            if (isset($_GET['page']) && $_GET['page'] == $i) {
                echo $i . " ";
            }
else {
                echo "<a href='view.php?page=$i'>$i</a> ";
            }
        }

        echo "</p>";

        // display data in table
        echo "<table>";
            echo "<tr>";
                echo "<th>ID</th>";
                echo "<th>Serie</th>";
                echo "<th>Titel</th>";
                echo "<th>Nummer</th>";
                echo "<th>Actie</th>";
            echo "</tr>";

            for ($i = $start; $i < $end; $i++) {
                if ($i == $total_results) {
                    break;
                }


                $result->data_seek($i);
                $row = $result->fetch_row();

            echo "<tr>";
                echo '<td>' . $row[0] . '</td>';
                echo '<td>' . $row[1] . '</td>';
                echo '<td>' . $row[2] . '</td>';
                echo '<td>' . $row[3] . '</td>';
                echo '<td><a href="records.php?id=' . $row[0] . '">Edit</a></td>';
                echo '<td><a href="delete.php?id=' . $row[0] . '">Delete</a></td>';
            echo "</tr>";
            }


            
            echo "</table>";
        }
else {
            echo "No results to display!";
        }
    }
else {
        echo "Error: " . $con->error;
}


$con->close();

?>


</body>
</html>

 


Ik heb de query voor de zoekfunctie veranderd in:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
$con->query("SELECT * FROM strips WHERE
      stripserie LIKE '%$search%' OR
      striptitel LIKE '%$search%'");


Wat doe ik nu weer fout??
 
PHP hulp

PHP hulp

08/12/2021 10:06:02
 
- Ariën -
Beheerder

- Ariën -

29/01/2018 20:27:45
Quote Anchor link
Er ontbreekt een LIMIT in je query.
 
Frank Nietbelangrijk

Frank Nietbelangrijk

29/01/2018 21:00:34
Quote Anchor link
Er wordt met data_seek gewerkt in deze code maar dat is wat mij betreft een verkeerde aanpak. Probleem is dat je eerst ALLE ( meer dan 1 miljoen misschien ? ) records laat klaarzetten en er dan maar tien raadpleegt. Zoals Ariën aangeeft zou je met een query met een LIMIT statement moeten werken.

Toevoeging op 29/01/2018 21:03:18:

En sorry dat ik het zeg maar hoe lang ga je met alles door elkaar werken? probeer PHP van HTML te scheiden en binnen PHP functionaliteiten van elkaar te scheiden. Je code wordt zo al snel een onoverzichtelijke bos spaghetti.
 
Klaas Buskes

Klaas Buskes

29/01/2018 21:12:50
Quote Anchor link
Ik heb het veranderd in:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
$result = $con->query("SELECT * FROM strips WHERE
      stripserie LIKE '%$search%' OR
      striptitel LIKE '%$search%' LIMIT 30"


maar krijg nog maar steeds 10 resultaten.

als ik op de tweede pagina klik, springt het naar het zoek formulier:


Code (php)
PHP script in nieuw venster Selecteer het PHP script
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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
<?php
require('db.php');

$per_page = 10;    

if ($result = $con->query("SELECT * FROM stripdata_klaas WHERE
      stripserie LIKE '%$search%' OR
      striptitel LIKE '%$search%' LIMIT 30"
)) {

    if ($result->num_rows != 0) {
        $total_results = $result->num_rows;
        $total_pages = ceil($total_results / $per_page);

        if (isset($_GET['page']) && is_numeric($_GET['page'])) {
            $show_page = $_GET['page'];

            if ($show_page > 0 && $show_page <= $total_pages) {
                $start = ($show_page -1) * $per_page;
                $end = $start + $per_page;
            }
else {
                $start = 0;
                $end = $per_page;
            }
        }
else {
            $start = 0;
            $end = $per_page;
        }



//  Toon de resultaten

echo "<p> <b>View Page:</b> ";
        for ($i = 1; $i <= $total_pages; $i++) {
            if (isset($_GET['page']) && $_GET['page'] == $i) {
                echo $i . " ";
            }
else {
                echo "<a href='strip-search.php?page=$i'>$i</a> ";
            }
        }

        echo "</p>";

        echo "<table>";
            echo "<tr>";
                echo "<th>ID</th>";
                echo "<th>Stripserie</th>";
                echo "<th>Striptitel</th>";
                echo "<th>Nummer</th>";
                echo "<th>Actie</th>";
            echo "</tr>";

            for ($i = $start; $i < $end; $i++) {
                if ($i == $total_results) {
                    break;
                }


                $result->data_seek($i);
                $row = $result->fetch_row();

            echo "<tr>";
                echo '<td>' . $row[0] . '</td>';
                echo '<td>' . $row[1] . '</td>';
                echo '<td>' . $row[2] . '</td>';
                echo '<td>' . $row[3] . '</td>';
                echo '<td><a href="records.php?id=' . $row[0] . '">Edit</a></td>';
                echo '<td><a href="delete.php?id=' . $row[0] . '">Delete</a></td>';
            echo "</tr>";
            }

            
            echo "</table>";  
        }
else {
            echo "No results to display!";
        }
    }
else {
        echo "Error: " . $con->error;
    }
else {

$con->close();

    
        
?>


    <div class="form">
        <form action ="" method = "post">
            <input name="search" type="text" size="30" placeholder="zoekterm"/>
            <input type="submit" value="Zoek ..."/>
        </form>
    </div>
<?php
}
?>


het gaat om 20 zoekopdrachten. Als het qua opbouw niets is, dan dank ik jullie voor jullie hulp en ga ik proberen om een en ander opnieuw te programmeren.
 
- Ariën -
Beheerder

- Ariën -

29/01/2018 21:12:56
Quote Anchor link
Als je straks meerdere lijsten wilt met paginanavigatie, dan wil je deze lappen code niet steeds herhalen.

Ook hier is de DRY-methode van toepassing:
'Don't Repeat Yourself'.

Dus deel de functies op in 'functions' of een 'class'.

Verder wil je met LIMIT niet steeds de eerste of de laatste items hebben, lijkt mij. Dus moet je steeds uit je aantallen records steeds een greep halen met bijv. 20 items.
Gewijzigd op 29/01/2018 21:16:17 door - Ariën -
 
Klaas Buskes

Klaas Buskes

29/01/2018 21:14:33
Quote Anchor link
Op naar de tekentafel dus. Bedankt in ieder geval :)
 
Frank Nietbelangrijk

Frank Nietbelangrijk

29/01/2018 21:23:57
Quote Anchor link
Om je een beetje op weg te helpen:

- Je bepaalt hoeveel resultaten je per pagina wilt tonen. Bijvoorbeeld 10.
- Je voert een query uit die enkel het aantal rijen telt. Bijvoorbeeld:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
SELECT COUNT(*) FROM strips

Stel dat dit er 125 zijn. Je kunt dan met een simpel rekensommetje uitrekenen hoeveel pagina's met resultaten je kunt tonen:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
<?php
$results_per_page
= 10;
$pages = ceil($rows / $results_per_page); // 125 / 10 afgerond naar boven = 13.
?>

- Vervolgens moet je bepalen op welke pagina we gebleven zijn:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
<?php
$currentpage
= 1;

if(isset($_GET['page'])) {
    $currentpage = $_GET['page'];
}


// even onnozelheden er uit filteren:
if($currentpage < 1 || $currentpage > $pages) {
    $currentpage = 1;
}

?>

- En nu kun je de tweede query in elkaar sleutelen:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
<?php
$startrow
= ($currentpage -1) * $results_per_page; // bijv pagina 3: 3-1 = 2 * 10 = 20. (laat rij 21 t/m 30 zien).
$query = "SELECT * FROM strips ORDER BY id LIMIT $startrow, $results_per_page";
?>
Gewijzigd op 29/01/2018 21:37:21 door Frank Nietbelangrijk
 
Thomas van den Heuvel

Thomas van den Heuvel

29/01/2018 22:42:29
Quote Anchor link
MySQL heeft een voorziening waarmee je een LIMIT-query kunt "flaggen" waarmee je aangeeft dat je ook geïnteresseerd bent in het totaal aantal resultaten, dus hoeveel resultaten dezelfde query zou opleveren als deze zonder de LIMIT-clause zou worden uitgevoerd.

Dit doe je als volgt:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
<?php
// de LIMIT-query
$sql = "SELECT SQL_CALC_FOUND_ROWS <de rest van je query> LIMIT x,y";
// voer hier je query uit...
// ...
// ... en direct hierna

$sql = "SELECT FOUND_ROWS()";
// deze tweede query geeft het totaal aantal resultaten van de LIMIT-query, maar dan zonder de LIMIT
// ...

?>
 
Frank Nietbelangrijk

Frank Nietbelangrijk

29/01/2018 22:58:34
Quote Anchor link
interessante optie Thomas. Een rondje google leverde echter teleurstellende tegenstrijdige berichten op qua snelheid..

https://stackoverflow.com/questions/186588/which-is-fastest-select-sql-calc-found-rows-from-table-or-select-count
Gewijzigd op 29/01/2018 23:04:47 door Frank Nietbelangrijk
 
Thomas van den Heuvel

Thomas van den Heuvel

29/01/2018 23:33:53
Quote Anchor link
Mja dat klopt, en dat blijft natuurlijk een beetje koffiedik kijken. Maar omdat het een specifiek MySQL-ding is zou je je zo kunnen voorstellen dat er ergens toch wel wat winst meegepakt zou kunnen worden. Het kan in ieder geval geen kwaad lijkt mij.

Zoals daar wordt aangehaald spelen indexes enzo (en aantal records, betrokken tabellen etc.) natuurlijk ook een rol.

Maar als het redelijk standaard queries zijn dan is dit natuurlijk interessant voor het verder automatiseren/standaardiseren van gepagineerde data.

En bij twijfel: gewoon benchmarken.

EDIT: dat soort (reacties op dat soort) topics neem ik altijd met een korrel zout, er heerst vaak een hoop verwarring, en soms worden verkeerde oorzaken voor traagheid (onterecht) toegeschreven aan dit soort constructies. De verwarring is dan natuurlijk compleet. En soms worden dus compleet idiote datasets/constructies verzonnen om dit soort dingen in een kwaad daglicht te stellen. Wat dat betreft: gewoon alles uitproberen en het goede behouden / meten is weten. Zou niet de eerste keer zijn dat iemand zegt "ik gebruik <X> niet want <verkeerde/ongefundeerde redenatie>".
Gewijzigd op 29/01/2018 23:38:12 door Thomas van den Heuvel
 
Frank Nietbelangrijk

Frank Nietbelangrijk

30/01/2018 09:12:03
Quote Anchor link
Er kunnen inderdaad een aantal kanttekeningen geplaatst worden bij dit soort berichten. Ook moeten we ons realiseren dat dit topic uit 2016 stamt en er misschien in tussentijd al performance updates doorgevoerd zijn.

Uit de tekst kun je ook opmaken dat het indexeren van de juiste kolommen erg belangrijk is maar dat is iets dat we eigenlijk al weten.
 



Overzicht Reageren

 
 

Om de gebruiksvriendelijkheid van onze website en diensten te optimaliseren maken wij gebruik van cookies. Deze cookies gebruiken wij voor functionaliteiten, analytische gegevens en marketing doeleinden. U vindt meer informatie in onze privacy statement.