0

I have a really large data set from SQL that i need to paginate.

I have an issue with my pagination code. The code does show the page number in the URL and it does give me pagination hyperlinks at the bottom of the table. However, any page I click on, it outputs the same exact portion of the sql datatable.

Also, I'm doing this in wordpress.

// define how many results you want per page
$results_per_page = 10;

// find out the number of results stored in database
$sql='SELECT * FROM ETF';
$result = mysqli_query($con, $sql);
$number_of_results = mysqli_num_rows($result);

// determine number of total pages available
$number_of_pages = ceil($number_of_results/$results_per_page);

// determine which page number visitor is currently on
if (!isset($_GET['page'])) {
  $page = 1;
} else {
  $page = $_GET['page'];
}

// determine the sql LIMIT starting number for the results on the displaying page
$this_page_first_result = ($page-1)*$results_per_page;

// retrieve selected results from database and display them on page
$sql='SELECT * FROM ETF LIMIT ' . $this_page_first_result . "," .$results_per_page;

$result = mysqli_query($con, $sql);

while($row = mysqli_fetch_array($result)) {
  echo $row['ETF'] . ' ' . $row['ETF NAME']. '<br>';
}


// display the links to the pages
for ($page=1;$page<=$number_of_pages;$page++) {
  echo '<a href="index.php/stocks/sec-forms/?page=' . $page . '">' . $page. '</a>';
}
Sᴀᴍ Onᴇᴌᴀ
  • 8,218
  • 8
  • 36
  • 58
Yousuf
  • 113
  • 1
  • 10
  • 2
    please remove the CAPS from the title, it's considered as **YELLING**. – Funk Forty Niner Nov 14 '17 at 02:15
  • 1
    You have to use `OFFSET` to instruct SQL to not just pull the first 10. Also you should ORDER BY something so the results are consistent. – serakfalcon Nov 14 '17 at 02:16
  • serakfalcon is right. An `OFFSET` is missing. Alternatively you can use two limit boundaries like so `SELECT * FROM tbl LIMIT 5,10;` Retrieves rows 6-15 – Hafenkranich Nov 14 '17 at 02:22

3 Answers3

0

Try:

$sql='SELECT * FROM ETF LIMIT ' . $results_per_page . ' OFFSET ' . $this_page_first_result;

Also as mentioned you should sort by a certain column with 'ORDER BY' for consistent results.

Stel
  • 126
  • 3
  • Thanks for the quick reply. After doing that, i get the following error: Warning: mysqli_fetch_assoc() expects parameter 1 to be mysqli_result, boolean given line 33 – Yousuf Nov 14 '17 at 15:24
  • I'm assuming you fixed this error based on comments below. If the same 10 rows are still always being displayed I would begin troubleshooting by displaying some of these variable. Start with displaying the SQL query to the screen, ie, after the line that creates the $sql string add something like: __echo $sql . '
    ';__ so we can see what exactly is being queried.
    – Stel Nov 14 '17 at 22:12
  • Hi Stel, I did as you said; i put the echo to my code. This is what it gave me: SELECT * FROM ETF LIMIT 10 OFFSET 0 – Yousuf Nov 16 '17 at 04:06
  • No matter which page i go to, the OFFSET stays at zero. Which is why the same part of the table gets repeated on every page. I suspect that my $_get['page'] is incorrect which is then feeding to $this_page_first_result; any ideas? – Yousuf Nov 16 '17 at 04:24
  • That narrows it down. I didn't notice this before, but the url does not look right. There should not be any slashes after index.php. This is probably preventing php from getting the 'page' variable from the url. So the display links line should be: **echo '' . $page. '';** – Stel Nov 16 '17 at 04:45
  • I changed it to what you suggested but it would keep saying page not found when i did. But i changed it to what Vykintas suggested below and i see an output but its stuck on the first 10 no matter which page im on. – Yousuf Nov 16 '17 at 17:08
  • This is the URL that shows up when i got to a certain page. statstreetx.com/index.php/stocks/sec-forms/74 In this case, page 74; see how it doesn't show ?page= this is probably what is causing the issue? – Yousuf Nov 16 '17 at 18:21
  • I see that the site is using Wordpress. There are issues with passing custom variables in the URL due to the way Wordpress handles them (if WP is not modified it basically strips and ignores them). I'm not sure of the specific fix for this, but the question has been raised before. The first and second answers here give some insight: https://stackoverflow.com/questions/4586835/how-to-pass-extra-variables-in-url-with-wordpress – Stel Nov 16 '17 at 20:47
  • I finally got the ?page= to show in the url. But my table is still not updating. Any ideas now? – Yousuf Nov 17 '17 at 18:58
  • 1
    Hey Stel, just an update, i figured out a work around to my situation after reading the stuff you suggested. At the end, i decided to bring up the current page the visitor is on and then parse the last portion which is the page number and use that for the offset value. I just have to figure out the first page and then get rid of all the hyperlinks. Thanks for all your help! I appreciate you taking the time. :) – Yousuf Nov 18 '17 at 01:35
0

You should change

$sql='SELECT * FROM ETF';
$result = mysqli_query($con, $sql);
$number_of_results = mysqli_num_rows($result);

to something like this

$count = mysqli_fetch_assoc(mysqli_query($con,"SELECT COUNT(*) AS RC FROM ETF"));
$number_of_results=$count['RC'];

because it is faster to get count from mysql (index if its a large table) instead of fetching all table data (because SELECT *...) for looping trough it just for row counting.

// retrieve selected results from database and display them on page
$sql='SELECT * FROM ETF LIMIT ' . $this_page_first_result . "," .$results_per_page;

You using good query, but using wrong function to get its results.

Query should be

$sql='SELECT * FROM ETF LIMIT ' . $results_per_page . "," .$this_page_first_result;

or:

$sql='SELECT * FROM ETF LIMIT ' . $results_per_page . " OFFSET " .$this_page_first_result;

Both of these work.

Change

while($row = mysqli_fetch_array($result)) {
  echo $row['ETF'] . ' ' . $row['ETF NAME']. '<br>';
}

to

while($row = mysqli_fetch_assoc($result)) {
  echo $row['ETF'] . ' ' . $row['ETF NAME']. '<br>';
}

because "mysqli_fetch_array" fetch array width numbered indexes (for example 0, 1, 2...) not a text ones you are trying to use, but "mysqli_fetch_assoc" does that you need.

Full code should be

<?php
$con=mysqli_connect('your server','login to database','database logins password','database name');
// define how many results you want per page
$results_per_page=10;
// find out the number of results stored in database
$count=mysqli_fetch_assoc(mysqli_query($con,"SELECT COUNT(*) AS RC FROM ETF"));
$number_of_results=$count['RC'];
// determine number of total pages available
$number_of_pages=ceil($number_of_results/$results_per_page);
// determine which page number visitor is currently on
if(!isset($_GET['page']))
{
    $page=1;
}
else
{
    $page=$_GET['page'];
}
// determine the sql LIMIT starting number (OFFSET) for the results on the displaying page
$this_page_first_result=($page-1)*$results_per_page;
// retrieve selected results from database and display them on page
$sql="SELECT * FROM ETF LIMIT $results_per_page,$this_page_first_result";
$result=mysqli_query($con, $sql);
// Loop to show results
while($row = mysqli_fetch_assoc($result))
{
    echo $row['ETF'].' '.$row['ETF NAME'].'<br>';
}
// display the links to the pages
for($page=1;$page<=$number_of_pages;$page++)
{
    echo'<a href="?page='.$page.'">'.$page.'</a> ';
}
mysqli_close($con);
    ?>
  • thanks for the suggestions vykintas; I tried it with OFFSET and it doesn't bring up any values. When i switch it back to the "," it gives me values but only shows the first 10 rows of mysql table, no matter which page i'm on. Any ideas? – Yousuf Nov 14 '17 at 19:13
  • thanks for the edit; results do show up now with the change. However, it is still repeating the same 10 rows of my sql data no matter which page im on. Maybe there is another part of my code that is the issue other than the limit? – Yousuf Nov 14 '17 at 20:29
  • Thank you so much for all your help everyone. It means a lot to me. Vykintas, i just copied and pasted the code. It doesn't give me an error but nothing shows up either. – Yousuf Nov 15 '17 at 17:55
  • I just did echo $page; and it turns out that the page number is being detected as 1 for every page im on. Is this a coding issue or could it be a wordpress theme issue? – Yousuf Nov 16 '17 at 04:49
  • When i echo $_GET['page'] it doesnt bring anything up. – Yousuf Nov 16 '17 at 15:21
  • I changed it but still staying stuck on the first page – Yousuf Nov 16 '17 at 17:07
  • This is the URL that shows up when i got to a certain page. http://statstreetx.com/index.php/stocks/sec-forms/74/ In this case, page 74; see how it doesn't show ?page= this is probably what is causing the issue? – Yousuf Nov 16 '17 at 18:20
  • 1
    Ya i figured out a work around to my strange URL situation. Now i'm able to pull page numbers. Thanks for all your help! I really appreciate it! – Yousuf Nov 18 '17 at 01:32
0

Using OFFSET and LIMIT for pagination of web pages leads to two bugs -- duplicated rows shown, and rows not shown.

Why?

  1. You are pondering the "first" 10 rows on one web page.
  2. Meanwhile a row is INSERTed or DELETEd that belongs in the first 10.
  3. You click [Next] and go to the page that shows the next 10 rows. But wait, it is not showing the "next" 10 rows, it is showing rows #11-20. And, since something changed in rows 1-10, the rows are not really continuing where you left off.

I just gave you a hint of how to avoid it -- "remember where you left off" instead of using OFFSET. More .

Rick James
  • 135,179
  • 13
  • 127
  • 222