php paging script for a search engine - php

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
}

Related

Sorting is not working with LIMIT while fetching results

I am currently working on a website which is basically search based. End users can search the members that are currently registered on the website. The registered users can avail 3 membership packages Golden, Silver and Basic. I have a pagination in place and when I try to sort the result based on the package, I get duplication of results on different pages. For example, if I get a user on page 3, he may also appear on, say, page 6. I don't know what i am doing wrong. Any help will be highly appreciated. I am pasting below my MySQL query that is fetching the result from the database.
SELECT * FROM users
LEFT JOIN prof_info
ON users.id = prof_info.user_id
WHERE (prof_info.work_country = 'Indonesia'
OR (prof_info.work_country ='' AND users.country = 'Indonesia'))
AND users.firstname !=''
ORDER BY users.membership DESC
LIMIT 0, 10
Membership packages have following database entry:
Golden=2, Silver=1, Basic=0. I want to be able to show Golden members in search result, than silver and afterwords basic members.
Code that creates pagination is
<?php
if (isset($_GET["page"])) { $current_page = $_GET["page"]; } else { $current_page=1; };
$limit = 1; // number of results per page
$start_from = ($current_page-1) * $limit;
if(isset($total_results)){
$nav = '';
$skip_links1 = 1;
$skip_links2 = 1;
for($page = 1; $page <= $total_pages; $page++)
{
if ($page == $current_page)
{
$nav .= " $page "; // no need to create a link to current page
}
else
{
if(($page > 2) && ($page < $total_pages-2) && ($page > $current_page + 2)){//number of pages exceeding 5
if($skip_links1 == 1)
$nav .= " ... ";
$skip_links1 =0;
}elseif($page >2 && $page < $current_page -2 ){
if($skip_links2 == 1)
$nav .= " ... ";
$skip_links2=0;
}else{
$nav .= "<a href='doctors.php?page=".$page."&country=".$_GET['country']."&city=".$_GET['city']."&speciality=".$_GET['speciality']."&name=".$_GET['name']."'>".$page."</a> ";
}
}
}
if ($current_page > 1)
{
$page = $current_page - 1;
$prev = " <a href='doctors.php?page=".$page."&country=".$_GET['country']."&city=".$_GET['city']."&speciality=".$_GET['speciality']."&name=".$_GET['name']."'><</a> ";
$first = " <a href='doctors.php?page=1&country=".$_GET['country']."&city=".$_GET['city']."&speciality=".$_GET['speciality']."&name=".$_GET['name']."'><<</a> ";
}
else
{
$prev = ' '; // we're on page one, don't print previous link
$first = ' '; // nor the first page link
}
if ($current_page < $total_pages)
{
$page = $current_page + 1;
$next = " <a href='doctors.php?page=".$page."&country=".$_GET['country']."&city=".$_GET['city']."&speciality=".$_GET['speciality']."&name=".$_GET['name']."'>></a> ";
$last = " <a href='doctors.php?page=".$total_pages."&country=".$_GET['country']."&city=".$_GET['city']."&speciality=".$_GET['speciality']."&name=".$_GET['name']."'>>></a> ";
}
else
{
$next = ' '; // we're on the last page, don't print next link
$last = ' '; // nor the last page link
} ?>
<div id="tableNav">
<?php
echo "<center>".$first . $prev . $nav . $next . $last."</center>";
?>
</div>
<?php
}//end of if(isset($total_results))
?>
First of all swap LEFT JOIN to INNER JOIN because you have on clause.
Secondly, it seems like you have duplicates in your table. You can get only 1 membership type per user, for example highest one by using this query
SELECT
*,MAX(users.membership)
FROM
users
INNER JOIN
prof_info ON users.id = prof_info.user_id
WHERE
(prof_info.work_country = 'Indonesia'
OR (prof_info.work_country = ''
AND users.country = 'Indonesia'))
AND users.firstname != ''
GROUP by users.id
ORDER BY users.membership DESC
LIMIT 0 , 10

show page numbering in PHP

I am using this coed in PHP to show next and previous buttons for records in a mysql database:
$sql="SELECT * from customer";
$rs=mysql_query($sql,$conn) or die(mysql_error());
$MaxRowsPerPage = 25;
$total_records = mysql_num_rows($rs);
$total_pages = ceil($total_records / $MaxRowsPerPage);
if(isset($_GET["page"])) {
$page = $_GET["page"];
} else {
$page=1;
}
$start_from = ($page-1) * $MaxRowsPerPage;
$sql.=" LIMIT $start_from, $MaxRowsPerPage";
I am echoing $total_records to show the total amount, how can i show the number from and to on the current page. for example, on page 1 it will be showing records 1 to 25 (because max rows per page is 25) and then page 2 will be showing records 26 to 50 and so on...
There a are many ways of doing this, but here's a simple pagination example I made. It will also show 1-25, 26-50 etc. It's heavily commented so it should be easy to understand.
<?php
// Connect to database
include 'includes/db_connect.php';
// Find total number of rows in table
$result = mysql_query("SELECT COUNT(*) FROM example_table");
$row = mysql_fetch_array($result);
$total_rows = $row[0];
// Set rows per page
$rows_per_page = 25;
// Calculate total number of pages
$total_pages = ceil($total_rows / $rows_per_page);
// Get current page
$current_page = (isset($_GET['p']) && $_GET['p'] > 0) ? (int) $_GET['p'] : 1;
// If current page is greater than last page, set it to last.
if ($current_page > $total_pages)
$current_page = $total_pages;
// Set starting post
$offset = ($current_page - 1) * $rows_per_page;
// Get rows from database
$result = mysql_query("SELECT * FROM example_table LIMIT $offset, $rows_per_page");
// Print rows
echo '<hr>';
while($row = mysql_fetch_array($result))
{
echo $row['id'].'<br />';
echo $row['text'];
echo '<hr>';
}
// Build navigation
// Range of pages on each side of current page in navigation
$range = 4;
// Create navigation link for previous and first page.
if ($current_page > 1)
{
$back = $current_page - 1;
echo ' PREV ';
if ($current_page > ($range + 1))
echo ' 1... ';
}
else
echo ' PREV ';
// Create page links, based on chosen range.
for ($i = $current_page - $range; $i < ($current_page + $range) + 1; $i++)
{
if ($i > 0 && $i <= $total_pages)
if ($i == $current_page)
echo ' [<strong>'.$i.'</strong>] ';
else
echo ' '.$i.' ';
}
// Create navigation link for next and last page.
if ($current_page != $total_pages)
{
$next = $current_page + 1;
if (($current_page + $range) < $total_pages)
echo ' ...'.$total_pages.' ';
echo ' NEXT ';
}
else
echo ' NEXT ';
?>

PHP Pagination with x amount of pages

Currently I have a functioning pagination script, although I'm missing on feature. At the moment it's possible for hundreds of pages to be showing in the $pages list, because there's no filter on to show between, for example, [1] [...] 5, 6, 7 [..] [45]. Here's my code:
/** Pagination **/
$limit = 7;
$query = "SELECT COUNT(*) FROM users";
$result = $db->prepare($query);
$result->execute();
$pages_query = $result->fetchColumn(0);
$count = number_format($pages_query);
$pages = ceil($pages_query / $limit);
$page = (isset($_GET['page'])) ? (int)$_GET['page'] : 1;
$start = ($page - 1) * $limit;
ob_start();
echo("<span class='alignright'>");
if ($pages >= 1 && $page <= $pages){
if($page > 1){
$next = ($page - 1);
$link = "?page=$next";
echo("<a class='paginate' href='$link'><i class='icon-caret-left'></i></a>");
}
for ($x=1; $x<=$pages; $x++){
echo ($x == $page) ? "<strong style='font-weight: bold!important;'><a class='paginate' href='?page=$x'>$x</a></strong>" : "<a class='paginate' href='?page=$x'>$x</a>";
}
if($page < $pages){
$next = ($page + 1);
$link = "?page=$next";
echo("<a class='paginate' href='$link'><i class='icon-caret-right'></i></a>");
}
echo("</span>");
if($count > 0){
echo("<span class='smalltext'>Page <strong class='half'>$page</strong> of $pages:</span>");
} else {
echo("<span class='smalltext'>There are <span class='half'>$count</span> results to display.</span>");
}
$pagintion = ob_get_clean();
(It's been stripped from other junk that was in it but that's the general frame.) Basically I'm trying to figure out how to limit it to have "between pages" down the bottom as specified in the top part of the question. Something like:
[<] [1] ... [4] [5] [6] ... [45] [>]
If that makes sense.
you can try LIMIT with in your query itself
SELECT * FROM TABLE_NAME LIMIT STARTING_RESULT_NUMBER, RESULTS_PER_PAGE
RESULTS_PER_PAGE is no.of items per page you want to display
STARTING_RESULT_NUMBER =(CURRENT_PAGE_NUMBER*RESULTS_PER_PAGE)
In order to change the list of pages to something like [<] [1] ... [4] [5] [6] ... [45] [>] rather than showing all pages numbers, you can replace your for loop by something like :
echo "<a class='paginate' href='?page=1'>1</a>";
if($page > 3) {echo "...";}
if($page > 2) {echo "<a class='paginate' href='?page=" . $x-1 . "'>" . $x-1 "</a>";}
if($page != 1 && $page != pages) {echo "<a class='paginate' href='?page=" . $x . "'>" . $x "</a>";}
if($page < $pages-1) {echo "<a class='paginate' href='?page=" . $x+1 . "'>" . $x+1 "</a>";}
if($page < $pages-2) {echo "...";}
if($pages >1) {echo "<a class='paginate' href='?page=1'>1</a>";}
Il will show the first page, the last pages, the current pages and the ones just before and just after.
My personal meaning with pagination is that it must be readable and simple to change later on.
I typed the following code based on you're example:
$totalPages = 145; //the total amount of pages
$selectedPage = 40; //the selected page
$pages = array(); //the array which is gonna hold the pages we need to display
$offset = 3; //the number of pages to select around the selected page
$closePages = range($selectedPage - $offset, $selectedPage + $offset); //select the pages that are in $offset of the selected page
array_filter($closePages, function($x) { //filter the pages below 1 and above $totalPages
return ($x <= $totalPages && $x >= 1 ? true : false );
});
array_push($pages, 1); //add the first page
array_push($pages, '...'); //add some dots
$pages = array_merge($pages, $closePages);
array_push($pages, '...'); //and again add some dots
array_push($pages, $totalPages); //add the last page
Then you use a foreach loop to display the pages:
foreach($pages as $page) {
if (is_numeric($page)) {
if ($page != $selectedPage) $content .= ' ' . $page . ' ';
else $content .= ' <strong>' . $page . '</strong> ';
} else
$content .= '[...]';
}
Some explanation after you're comment on this answer:
The $totalPages variable must be the total amount of pages on the page (from you're example) and the $selectedPage is the page that is selected at this moment.
$totalPages = ceil($pages_query / $limit);
$selectedPage = isset($_GET['page']) ? $_GET['page'] : 1;

Automatic pagination for status board program

i have more data's in my mysql database. i want to display the data, per page 10 data only i need to display, for this i wrote pagination code. its working very fine but i want to run that pagination automatically that means automatically after few seconds the page turns to second page then third page etc... but i don't know how to implement please help anyone. Here below the sample code for reference:
<?php
include "config.inc";
$sql = "SELECT COUNT(*) FROM test";
$result = mysql_query($sql) or trigger_error("SQL", E_USER_ERROR);
$r = mysql_fetch_row($result);
$numrows = $r[0];
$rowsperpage = 3;
$totalpages = ceil($numrows / $rowsperpage);
if (isset($_GET['currentpage']) && is_numeric($_GET['currentpage'])) {
$currentpage = (int) $_GET['currentpage'];
} else {
$currentpage = 1;
}
if ($currentpage > $totalpages) {
$currentpage = $totalpages;
}
if ($currentpage < 1) {
$currentpage = 1;
}
$offset = ($currentpage - 1) * $rowsperpage;
$sql = "SELECT * FROM test LIMIT $offset, $rowsperpage";
$result = mysql_query($sql) or trigger_error("SQL", E_USER_ERROR);
while ($list = mysql_fetch_array($result)) {
echo $list['mark_cut_weld'] . " : " . $list['mark_cut_inves'] . "<br />";
}
$range = 3;
if ($currentpage > 1) {
echo " <a href='{$_SERVER['PHP_SELF']}?currentpage=1'><<</a> ";
$prevpage = $currentpage - 1;
echo " <a href='{$_SERVER['PHP_SELF']}?currentpage=$prevpage'><</a> ";
}
for ($x = ($currentpage - $range); $x < (($currentpage + $range) + 1); $x++) {
if (($x > 0) && ($x <= $totalpages)) {
if ($x == $currentpage) {
echo " [<b>$x</b>] ";
} else {
echo " <a href='{$_SERVER['PHP_SELF']}?currentpage=$x'>$x</a> ";
}
}
}
if ($currentpage != $totalpages) {
$nextpage = $currentpage + 1;
echo " <a href='{$_SERVER['PHP_SELF']}?currentpage=$nextpage'>></a> ";
echo " <a href='{$_SERVER['PHP_SELF']}?currentpage=$totalpages'>>></a> ";
}
?>
Above code, i just fetch the data from mysql database by php. then set the data per page is 3. i just get the total count and then divide by number of rows into rows per page... then automatically it will display the data.
My target is display the data from database. per page 10 data's and then automatically it move to next page for next 10 data without any action click or submit...
Because it is status board program.. we going to display by big tv in factory... so workers can see the status of the work in this big tv.
You can set a header redirect to redirect to next page.
For example the following code will redirect you to next page in 10 seconds.
header('Refresh: 10; URL='.$_SERVER['PHP_SELF'].'?page='.$next_page);
Make sure you set the header before you echo anything in PHP.
You are going to want to use javascript to set timeouts that will redirect the location to the next page every so often.
For example, add this to the bottom of your HTML body:
<script type="text/javascript">
function switchPage(){
window.location = "<?php echo $next_page?>"; // set the next page of results to view.
}
setTimeout(switchPage,60*1000); // call callback every minute
</script>
The variable $next_page will need to be a URL to the next set of results using PHP.
To have it repeat you will need a modulus on the PHP side that flips back to page 0 when the end of the results has been reached.
<?php
$next_page_count = ++$currentpage % $totalpages;
$next_page = $_SERVER['PHP_SELF'] . '?currentpage=' . $next_page_count;

Pagination links on top of the page, before actual script

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.

Categories