Calculating number of results in a specific page using pagination - php

I have a search result from MySQL query or Array or something else. The result gave a variable $totalfiles say for example 25. The number of results is limited to $limit, here 12. The maximum number of pages calculated, $maxpages, will be 3.
As we consider the case, we will get 12 results for pages 1 and 2, and 1 for page 3.
What is the easiest way to predict (or calculate) the number of results in a specific page using variables $totalfiles, $limit, $maxpages and $pagenumber using PHP? I don't think all these 4 variables are necessary for doing this.

The only page that is allowed to have a number that is different from $limit is the last one. Don't forget that. And the last page will always have the remainder of the integer division
$last_page_items = $totafiles % $limit;
If $last_page_items is 0, means that you have all pages with $limit items
also,
$pages = ceil($totalfiles / $limit);

R = Number of rows on a given page, P, where P starts at 1.
T = Total rows
L = Rows per page
R = T - ((P-1) * L)
Then just add a check afterwards to set R to 0 if R < 0.
Code:
function get_num_rows_on_page($page, $total_rows, $per_page) {
$on_page = $total_rows - ( ($page-1) * $per_page );
return $on_page < 0 ? 0 : $on_page;
}

Max pages: Total files, divided by the limit. If the remainder is greater than 0, add one.
$maxpages = $totalfiles/$limit;
if ($totalfiles % $limit > 0) $maxpages++;
Number on current page: if Page number less than Max page, there are limit results. If Page number is the Max page, there are (Remainder of Total Files divided by limit) results if that remainder is greater than 0, otherwise limit.
$results = $limit;
$rem = $totalfiles % limit;
if ($pagenumber == $maxpages && $rem > 0) $results = $rem;

If you want to distribute the results evenly in the maximum number of pages, which is 3 as you have suggested, you can use:
$results_per_page = ($totalfiles/$maxpages);
Otherwise, you already have the number of results per page calculated on your $limit variable.

Try this:
function getPageSize($total, $maxpages, $pagenumber){
$itemsperpage=intval($total/$maxpages);
if($pagenumber == $maxpages){
$itemslastpage=abs($total-($itemsperpage*$maxpages));
return $itemslastpage;
}else{
return $itemsperpage;
}
}
// should print '5'
echo getPageSize(29,6,6) . "\n";
// should print '7'
echo getPageSize(14,2,1) . "\n";
Note that $limit is not needed as it is only used to control results from database.

Related

PHP: How to check if a number is between collection of two numbers

i have a code like this
$count=15; // i manually initialising a value that not satisfying by folling condition
$low_limit=0;
$up_limit=10;
$num_pages=0;
(some loop) {
if (($count >= $low_limit) && ($count <= $up_limit))
{
$num_pages=$numpages+1;
echo $num_pages;
}
$low_limit=$up_limit+1;
$up_limit=$up_limit+10;
} // loop ends
my logic was
$count is a variable // this value can be frequently changed
$low_limit and $up_limit are value ranges // 0-10 , 10-20 , 20-30 ,etc
$num_pages is a variable that return
1 if $low_limit= 0 and $up_limit= 10
2 if $low_limit= 11 and $up_limit= 20
3 if $low_limit= 21 and $up_limit= 30 and so on
here the $low_limit and $up_limit can be any number (but multiple of 10). it may be upto 50,000.
what will be in some loop .?
How i construct this program, i searched a lot, but i only find programs which checks a number between a range.
Any help would be greately appreciated.
Due to comments above, it should works as expected:
$count = 34; // any number
$per_page = 10; // it's fixed number, but...
$num_page = ceil($count / $per_page); // returns 4
$low_limit = ($num_page - 1) * $per_page; // returns 30
$up_limit = $num_page * $per_page; // returns 40
Between record number 30 and record number 40 are 11 records, not 10.
There are more ways how to fix that:
1. compare < ... <=: $low_limit < $count <= $up_limit
2. compare <= ... <: $low_limit <= $count < $up_limit
3. set limits 1-10, 11-20, 21-30, etc. (simply +1 to $low_limit on 4th line above)
4. set limits 0-9, 10-19, 20-29, etc. (simply -1 to $up_limit on 5th line above)

How to limit MySQL query result to specific results?

I have a news table in MySQL Database I query the table and show the title of the news in one PHP pages but now the table getting bigger so I want to divide the results into pages I mean to show each 50 news title in one page (pagenation).
I use this query to bring the news :
SELECT news.*, categories.category, users.username
FROM news INNER JOIN
users on news.user_id = users.id INNER JOIN
categories on categories.id = news.category_id
order by news.timestamp DESC
limit $min,$max
and this is part of the PHP page (How I calculate the max and min)
$news_per_page = 50;
if(!empty($_GET['p_n']))
{
$p_n = $_GET['p_n'];
$max = $news_per_page*$p_n;
$min = ($max - $news_per_page);
}
else
{
$p_n = 1;
$max = 50;
$min = 0;
}
$news = all_news($max,$min);
The sql giving me wrong result when i pass the limits I do not know why. Is it wrong to specify the max and min of sql query by this way?? Should I correct something in this code?
The LIMIT clause, as explained in the docs, takes arguments offset and count. So if you want to get, for example, results from 201 to 250, you would use LIMIT 200, 50. Start by renaming your variables $min and $max to $offset and $count, and from there everything will fall into place.
Pseudocode:
offset = (requestedPageNumber - 1) * rowsPerPage;
count = rowsPerPage;
PHP Code:
(assuming page number is 0-based)
$rowsPerPage = 50;
$page = empty($_GET['p_n']) ? 0 : $_GET['p_n'];
$offset = $rowsPerPage * (int) $page;
$news = all_news($offset, $rowsPerPage);
If you've got problems handling pagination properly, I suggest you use some code that is working, for example a pagination class that takes three parameters:
The current page.
The total count.
The number of items per page.
And then that class will generate the LIMIT clause for you. Example:
$pageNumber = 1;
$totalCount = 17;
$perPage = 5;
$pagination = new LimitPagination($pageNumber, $totalCount, $perPage);
echo $pagination, "\n";
This would output
LIMIT 0, 5
because you'er on the first page. Such a class then could also filter out those problems you have here, for example setting to a negative page - just automatically. And also it can provide a lot of extra data, like the next and previous page, the current page, the number of total pages, if it is the first or the last page and what not:
$pagination->setPage(-2);
echo $pagination, "\n";
echo "Current: ", $pagination->getPage(),
"; Total: ", $pagination->getTotalPages(),
"; Previous: ", $pagination->getPreviousPage(),
"; Next: ", $pagination->getNextPage(),
"\n";
Output:
LIMIT 0, 5
Current: 1; Total: 4; Previous: 1; Next: 2
This is then easy to integrate with different code, including yours:
$pagination = new LimitPagination($_GET['p_n'], $totalCount, 50);
$limit = sprintf("%d, %d", $pagination->getOffset(), $pagination->getCount());
This should easily do it. Class is here as Gist: https://gist.github.com/4469154
You need to set start (this you can achieve by using current page and per page property) and the second information is how many results you want (again per page property).
LIMIT . ($p_n - 1) * $news_per_page .', ' . $news_per_page
So, in your script it will be:
if(!empty($_GET['p_n']))
{
// You need to protect your variables for SQL injection. For numbers (int) or integer() function it is enough.
$p_n = (int) $_GET['p_n'];
$max = (int) $news_per_page;
$min = (int) ($p_n - 1) * $news_per_page;
}
else
{
$p_n = 1;
$max = 50;
$min = 0;
}
The correct code is:
$news_per_page = 50;
if(!empty($_GET['p_n']))
{
$p_n = intval($_GET['p_n']);
$min = ($p_n-1) * $news_per_page;
$max = $news_per_page;
}
else
{
$p_n = 1;
$max = 50;
$min = 0;
}
$news = all_news($max,$min);
While $_GET['p_n'] is page_number you dont' need to make any multiplies

Dynamic pagination by counting the number of rows and a pre-defined result per page (rpp) with PHP

I whipped up some code to count the number of rows from my database, and through a little script, display "Page : 1 2 3 4 5" etc.
Here is my code:
$totalRows = mysql_num_rows
$rpp = 20
$totalPages = ceil($totalRows/$rpp);
$i;
for (i=0; i<totalPages; i++){
echo "Page: " . "<a href='index.php?page=\"$i\"rpp=20>\"$i\"</a>";
}
Does this look good? Do I need anything else?
EDIT 1: Added ceil() to round up. No more missing results :-)!
I think you need to round $totalPages to the next highest integer, ie.
$totalPages = ceil($totalRows/$rpp);

php calculation solution for pagination

I have a variable $total which is the total number of results and $page which is the page number. The result is limited to 12 per page.
Suppose if $total is 24, the script may return 1 and 2 for $page=1 and $page=2 respectively. It should also return 1 if the input number is less than 1 (negative or zero) or if the number is greater than 2
Again, suppose if $total is 25, the script may return 1, 2 and 3 for $page=1, $page=2 and $page=3 respectively. It should also return 1 if the input number is less than 1 (negative or zero) or if the number is greater than 1
Here's one way to calculate it:
// Assuming you have the $total variable which contains the total
// number of records
$recordsPerPage = 12;
// Declare a variable which will hold the number of pages required to
// display all the records, when displaying #recordsPerPage records on each page
$maxPages = 1;
if($total > 0)
$maxPages = (($total - 1) / $recordsPerPage) + 1;
// $maxPages now contains the number of pages required. you can do whatever
// it is you need to do with it. It wasn't clear from the question..
return $maxPages;
Further, if you wanted to generate an array containing the indexes of each available page you could just do this:
$pages = array();
for($i = 1; $i <= $maxPages; i++)
{
array_push($pages, $i);
}
print_r($pages);

Calculating offset for a for loop

I'm trying to do pagination on an array that ive got and currently im looping through it with a for loop like this
for($i = $pages->low;$i<$total;++$i)
What I need to figure out is how to get the $total variable to an be calculated based on the current page and the count of rows so the loop works correctly for the amount of items in the array.
I've got the following variables:
$pages->low (equals the number of rows the pagination has already been through
e.g. Page 1 = 0, Page 2 = 5, Page 3 = 10 etc...
$pages->total_items (explains itself)
$pages->current_page
$pages->ipp (items per page, FYI 5)
So what formula would I use to calculate the amount of rows the loop should go through so for example if there was 13 items in total in the array and 5 results per page, on page one $total should equal 5, page two should equal 10 and page three should equal 13 etc?
Thanks
$total = min($pages->ipp * ($pages->current_page + 1), $pages->total_items);
It does the obivous, but limits it the the total number of items.
Though I personally would simply use a LimitIterator here.
$start_from = ($current_page - 1) * $per_page;
From Kohana's pagination module:
$this->total_pages = (int) ceil($this->total_items / $this->items_per_page);
$this->current_page = (int) min(max(1, $this->current_page), max(1, $this->total_pages));
$this->current_first_item = (int) min((($this->current_page - 1) * $this->items_per_page) + 1, $this->total_items);
$this->current_last_item = (int) min($this->current_first_item + $this->items_per_page - 1, $this->total_items);
$this->previous_page = ($this->current_page > 1) ? $this->current_page - 1 : FALSE;
$this->next_page = ($this->current_page < $this->total_pages) ? $this->current_page + 1 : FALSE;
$this->first_page = ($this->current_page === 1) ? FALSE : 1;
$this->last_page = ($this->current_page >= $this->total_pages) ? FALSE : $this->total_pages;
$this->offset = (int) (($this->current_page - 1) * $this->items_per_page);
not clear, why if there was 13 items on page one total should be equal to 5 ???
For me if you are trying to show the $pages->ipp next items on pages 2 juste go from $pages->low to $pages->low + $pages->ipp

Categories