PHP session variable loses data when used in a page that uses pagination script.
I'm using PHP pagination using $_GET[]. When the url looks like example.com/folder/index.php?page=2 the session does not work. But it works fine when the url is like example.com/folder/index.php.
How can I keep the session data persistent when using along with pagination script?
Edit:
Yes I am using session_start() at the top of the page.
session_start();
$page = (!isset($_GET['page']))? 1 : (int)$_GET['page'];
$prev_link = ($page - 1);
$next_link = ($page + 1);
/* Max results per page */
$max_results = 20;
/* Calculate the offset */
$from = (($page * $max_results) - $max_results);
$stmt3 = $dbh->prepare("SELECT COUNT(id) FROM my_table");
$stmt3->execute();
$row3 = $stmt3->fetch(PDO::FETCH_NUM);
if(!$row3)
{
die('Could not get data.');
}
$total_results = $row3[0];
$total_pages = ceil($total_results / $max_results);
$pagination = '';
/* Create a PREV link if there is one */
if($page > 1)
{
$pagination .= "<a class='pagination_link' href='http://example.com/folder/index.php?page=".$prev_link."' style='padding:1%;'>Previous</a>";
}
/* Loop through the total pages */
for($i = max(1, $page - 5); $i <= min($page + 5, $total_pages); $i++)
{
if(($page) == $i)
{
$pagination .= "<span style='padding:1%;font-weight:bold;'>$i</span>";
}
else
{
$pagination .= "<a class='pagination_link' href='index.php?page=".$i."' style='padding:1%;'>".$i."</a>";
}
}
/* Print NEXT link if there is one */
if($page < $total_pages)
{
$pagination .= "<a class='pagination_link' href='http://example.com/folder/index.php?page=".$next_link."' style='padding:1%;'> Next</a>";
}
In each of your php pages that you wish to utilise PHP Sessions, please make sure that the following line is at the top of your PHP pages
<?php session_start(); ?>
This ensures that session data is carried across pages
I have a pagination script which works. The first page has a 'next' link, the last page should have a 'previous' link and the ones in between have both. The problem is that the last page doesnt show it 'previous' link.
Heres the code
include '../inc/connect.php';
//paganation settings
$per_page = 2;
$pages_query = mysqli_query($link, "SELECT COUNT(`id`) FROM `gallery`") or
die(mysqli_error($link));
$result = mysqli_fetch_array($pages_query, MYSQLI_NUM);
$pages = $result[0] / $per_page;
$page = (isset($_GET['page']) AND (int)$_GET['page'] > 0) ? (int)$_GET['page'] : 1;
$start = ($page - 1) * $per_page;
$last = ($pages - 1) / $per_page;
$prev = $page - 1;
$next = $page + 1;
//query the db
$q =mysqli_query($link, "SELECT * FROM gallery
ORDER BY id DESC
LIMIT $start, $per_page");
//find out the page we are on and display next and previous links accordingly
if ($page >= 1 && $page < $pages){
echo "<span class='next'>";
echo "Next page ";
echo "</span>";
if ($page >=2){
echo "<span class='prev'>";
echo "Previous page ";
echo "</span>";
}
}
else if ($page > $pages + 1){
echo 'No more images in the database';
}
//display images
while($row=mysqli_fetch_array($q)){
echo "<a href='{$row['filename']}' rel='thumbnail'>
<img class='nailthumb-container' src='{$row['filename']}'
alt='{$row['description']}.Image' title='{$row['description']}' />
</a>";
}
The last page link is falling under the ($page < $pages) test, and it probably shouldn't.
if ($page >= 1){
if ($page < $pages) {
echo "<span class='next'>";
echo "Next page ";
echo "</span>";
}
if ($page >=2){
echo "<span class='prev'>";
echo "Previous page ";
echo "</span>";
}
}
Change it to this will work i think, on your last page $page is equal to $pages instead of smaller than $pages:
if ($page >= 1 && $page <= $pages){...}
i have a paging script
for($page = 1; $page <= $maxPage; $page++)
{
if ($page == $pageNum)
{
$nad .= " $page "; // no need to create a link to current page
}
else
{
$nad .= " $page ";
}
}
that will show pages for the search query. I want to limit the amount of pages it shows to 5, because currently it shows every page, which is a problem,
say if there were 5000 rows and 5 rows per page, it would show 1000 pages. How do i limit that to 5?
You can use the min() and the max() functions:
$firstPage = max(1, $pageNum-5);
$lastPage = min($maxPage, $pageNum+5);
for($page = $firstPage; $page <= $lastPage; $page++)
{
// no changes here
}
I have a simple navigation php script which works ok.
The only problem is that I need to find a way to display the pagination links on top of the page instead of the bottom.
So for me a newb, it seems impossible since I have to show the pagination links before the actual navigation variables are being declared.
Can this be done?
Here is the script:
<?
$numrows = '600';
$rowsperpage = 20;
$totalpages = ceil($numrows / $rowsperpage);
if ($currentpage > $totalpages){ $currentpage = $totalpages; }
if ($currentpage < 1){ $currentpage = 1; }
$offset = ($currentpage - 1) * $rowsperpage;
HERE I query the data from the table and basically fill in the page.
Now starts the pagination links:
$range = 3;
if ($currentpage > 1) {
echo 'First';
}
$prevpage = $currentpage - 1;
echo 'Previous';
for ($x = ($currentpage - $range); $x < (($currentpage + $range) + 1); $x++) {
if (($x > 0) && ($x <= $totalpages)) {
if($x == $currentpage){
echo '<span class="current">'.$x.'</span>';
} else {
echo ''.$x.'';
}
}
}
if ($currentpage != $totalpages){
$nextpage = $currentpage + 1;
echo 'Next';
echo 'Last';
}
?>
When I do anything in PHP I do the following
<?php
//Calculate anything I need for the page to be displayed
//Build the html page and fill in variables where needed
?>
You may also want to look into frameworks like smarty that separate the logic from the template designs. PHP is really a templating language in itself but I actually quite like using smarty.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question appears to be off-topic because it lacks sufficient information to diagnose the problem. Describe your problem in more detail or include a minimal example in the question itself.
Closed 9 years ago.
Improve this question
I'm looking for an example algorithm of smart pagination. By smart, what I mean is that I only want to show, for example, 2 adjacent pages to the current page, so instead of ending up with a ridiculously long page list, I truncate it.
Here's a quick example to make it clearer... this is what I have now:
Pages: 1 2 3 4 [5] 6 7 8 9 10 11
This is what I want to end up with:
Pages: ... 3 4 [5] 6 7 ...
(In this example, I'm only showing 2 adjacent pages to the current page)
I'm implementing it in PHP/Mysql, and the "basic" pagination (no trucating) is already coded, I'm just looking for an example to optimize it... It can be an example in any language, as long as it gives me an idea as to how to implement it...
Here is some code based on original code from this very old link. It uses markup compatible with Bootstrap's pagination component, and outputs page links like this:
[1] 2 3 4 5 6 ... 100
1 [2] 3 4 5 6 ... 100
...
1 2 ... 14 15 [16] 17 18 ... 100
...
1 2 ... 97 [98] 99 100
<?php
// How many adjacent pages should be shown on each side?
$adjacents = 3;
//how many items to show per page
$limit = 5;
// if no page var is given, default to 1.
$page = (int)$_GET["page"] ?? 1;
//first item to display on this page
$start = ($page - 1) * $limit;
/* Get data. */
$data = $db
->query("SELECT * FROM mytable LIMIT $start, $limit")
->fetchAll();
$total_pages = count($data);
/* Setup page vars for display. */
$prev = $page - 1;
$next = $page + 1;
$lastpage = ceil($total_pages / $limit);
//last page minus 1
$lpm1 = $lastpage - 1;
$first_pages = "<li class='page-item'><a class='page-link' href='?page=1'>1</a></li>" .
"<li class='page-item'><a class='page-link' href='?page=2'>2</a>";
$ellipsis = "<li class='page-item disabled'><span class='page-link'>...</span></li>";
$last_pages = "<li class='page-item'><a class='page-link' href='?page=$lpm1'>$lpm1</a></li>" .
"<li class='page-item'><a class='page-link' href='?page=$lastpage'>$lastpage</a>";
$pagination = "<nav aria-label='page navigation'>";
$pagincation .= "<ul class='pagination'>";
//previous button
$disabled = ($page === 1) ? "disabled" : "";
$pagination.= "<li class='page-item $disabled'><a class='page-link' href='?page=$prev'>« previous</a></li>";
//pages
//not enough pages to bother breaking it up
if ($lastpage < 7 + ($adjacents * 2)) {
for ($i = 1; $i <= $lastpage; $i++) {
$active = $i === $page ? "active" : "";
$pagination .= "<li class='page-item $active'><a class='page-link' href='?page=$i'>$i</a></li>";
}
} elseif($lastpage > 5 + ($adjacents * 2)) {
//enough pages to hide some
//close to beginning; only hide later pages
if($page < 1 + ($adjacents * 2)) {
for ($i = 1; $i < 4 + ($adjacents * 2); $i++) {
$active = $i === $page ? "active" : "";
$pagination .= "<li class='page-item $active'><a class='page-link' href='?page=$i'>$i</a></li>";
}
$pagination .= $ellipsis;
$pagination .= $last_pages;
} elseif($lastpage - ($adjacents * 2) > $page && $page > ($adjacents * 2)) {
//in middle; hide some front and some back
$pagination .= $first_pages;
$pagination .= $ellipsis
for ($i = $page - $adjacents; $i <= $page + $adjacents; $i++) {
$active = $i === $page ? "active" : "";
$pagination .= "<li class='page-item $active'><a class='page-link' href='?page=$i'>$i</a></li>";
}
$pagination .= $ellipsis;
$pagination .= $last_pages;
} else {
//close to end; only hide early pages
$pagination .= $first_pages;
$pagination .= $ellipsis;
$pagination .= "<li class='page-item disabled'><span class='page-link'>...</span></li>";
for ($i = $lastpage - (2 + ($adjacents * 2)); $i <= $lastpage; $i++) {
$active = $i === $page ? "active" : "";
$pagination .= "<li class='page-item $active'><a class='page-link' href='?page=$i'>$i</a></li>";
}
}
}
//next button
$disabled = ($page === $last) ? "disabled" : "";
$pagination.= "<li class='page-item $disabled'><a class='page-link' href='?page=$next'>next »</a></li>";
$pagination .= "</ul></nav>";
if($lastpage <= 1) {
$pagination = "";
}
echo $pagination;
foreach ($data as $row) {
// display your data
}
echo $pagination;
Kinda late =), but here is my go at it:
function Pagination($data, $limit = null, $current = null, $adjacents = null)
{
$result = array();
if (isset($data, $limit) === true)
{
$result = range(1, ceil($data / $limit));
if (isset($current, $adjacents) === true)
{
if (($adjacents = floor($adjacents / 2) * 2 + 1) >= 1)
{
$result = array_slice($result, max(0, min(count($result) - $adjacents, intval($current) - ceil($adjacents / 2))), $adjacents);
}
}
}
return $result;
}
Example:
$total = 1024;
$per_page = 10;
$current_page = 2;
$adjacent_links = 4;
print_r(Pagination($total, $per_page, $current_page, $adjacent_links));
Output (# Codepad):
Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 4
[4] => 5
)
Another example:
$total = 1024;
$per_page = 10;
$current_page = 42;
$adjacent_links = 4;
print_r(Pagination($total, $per_page, $current_page, $adjacent_links));
Output (# Codepad):
Array
(
[0] => 40
[1] => 41
[2] => 42
[3] => 43
[4] => 44
)
I started from the lazaro's post and tried to make a robust and light algorithm with javascript/jquery...
No additional and/or bulky pagination libraries needed...
Look on fiddle for an live example: http://jsfiddle.net/97JtZ/1/
var totalPages = 50, buttons = 5;
var currentPage = lowerLimit = upperLimit = Math.min(9, totalPages);
//Search boundaries
for (var b = 1; b < buttons && b < totalPages;) {
if (lowerLimit > 1 ) { lowerLimit--; b++; }
if (b < buttons && upperLimit < totalPages) { upperLimit++; b++; }
}
//Do output to a html element
for (var i = lowerLimit; i <= upperLimit; i++) {
if (i == currentPage) $('#pager').append('<li>' + i + '</li> ');
else $('#pager').append('<li><em>' + i + '</em></li> ');
}
List<int> pages = new List<int>();
int pn = 2; //example of actual pagenumber
int total = 8;
for(int i = pn - 9; i <= pn + 9; i++)
{
if(i < 1) continue;
if(i > total) break;
pages.Add(i);
}
return pages;
I made a pagination class and put in on Google Code a while ago. Check it out its pretty simple
http://code.google.com/p/spaceshipcollaborative/wiki/PHPagination
$paging = new Pagination();
$paging->set('urlscheme','class.pagination.php?page=%page%');
$paging->set('perpage',10);
$paging->set('page',15);
$paging->set('total',3000);
$paging->set('nexttext','Next Page');
$paging->set('prevtext','Previous Page');
$paging->set('focusedclass','selected');
$paging->set('delimiter','');
$paging->set('numlinks',9);
$paging->display();
I would use something simple on the page you are showing the paginator, like:
if (
$page_number == 1 || $page_number == $last_page ||
$page_number == $actual_page ||
$page_number == $actual_page+1 || $page_number == $actual_page+2 ||
$page_number == $actual_page-1 || $page_number == $actual_page-2
) echo $page_number;
You can adapt it to show each 10 or so pages with % operator ...
I think using switch() case would be better in this case, I just don't remember the syntax now
Keep it Simple :)
If it's possible to generate the pagination on the client, I would suggest my new Pagination plugin: http://www.xarg.org/2011/09/jquery-pagination-revised/
The solution to your question would be:
$("#pagination").paging(1000, { // Your number of elements
format: '. - nncnn - ', // Format to get Pages: ... 3 4 [5] 6 7 ...
onSelect: function (page) {
// add code which gets executed when user selects a page
},
onFormat: function (type) {
switch (type) {
case 'block': // n and c
return '<a>' + this.value + '</a>';
case 'fill': // -
return '...';
case 'leap': // .
return 'Pages:';
}
}
});
The code of the CodeIgniter pagination-class can be found on GitHub
(what you call) Smart pagination can be achieved by configuration.
$config['num_links'] = 2;
The number of "digit" links you would like before and after the
selected page number. For example, the number 2 will place two digits
on either side, as in the example links at the very top of this page.