Simple (but powerful) paging function

Gewalop 6 Tallied Votes 2K Views Share

Hi,
- Why use paging?
It's not really cool to print out all 2000 rows you have in a table to the page, so it'd be nice to page them.

Special cases?
Yeah, if you have 1000 rows.. and you've set the maximum row per page to 20, well.. you're gonna get 50 links for your pages.. so I took care of that. How? I only show the first costume number of page links, and the more you navigate, the more pages you'll see.

Parameters:
1- The maximum number of results you want in each page.
2- The maximum number of pages links you want in the page.
3- The query you've used to get your results.
4- The page that has your results.


Example (call the function in the place you want to put the page links)

<?php
pageThis(20, 10, "SELECT * FROM notes", notes.php);
?>
epicrevolt commented: THANK YOU! +1
//Preparing --Start--
function pageThis($max, $max_page_links, $query, $page_link){
//Uncomment the next 4 lines if don't wish to use this as a function
//$page_link="paged.php";
//$max=30;//Maximum items per page (rows)
//$max_page_links=10;//Maximum links number in the page
//$query="select * from some_table";//Your query
$num_stuff=mysql_num_rows(mysql_query($query));//Getting the total possible rows
if (isset($_GET['page'])&&$_GET['page']>0){
    $start=intval($_GET['page'])-1;//Now the page number make more sense (page=1 is actually the first page)
    $current_page=intval($_GET['page']);//Some cleaning (SQL Injection prevention, and get rid of negative numbers)
}
//If no parameters passed.. just give the first page
else {
    $current_page=1;
    $start=0;
}
//If a large page numbre passed (more than there actually is) just give the last page
if ($current_page>ceil($num_stuff/$max)){
    	$current_page=ceil($num_stuff/$max);
    	$start=ceil($num_stuff/$max)-1;
}
$start*=$max;//Which row to start with
$get_stuff_query.=" limit $start, $max";//Adding the limit
//Preparing --End--


//Actual paging --Start--
if ($num_stuff>$max){//Is there any need for pagin?
	if ($current_page>1){//Making previous page & first page links when needed
                $previous_page=$current_page-1;//previousious means -1
                echo "<a style=\"text-decoration: none;\" href=\"".$page_link."page=1\">|<</a>  ";//First page is the page number.. you guessed it right.. 1
                echo "<a style=\"text-decoration: none;\" href=\"".$page_link."page=$previous_page\"<<</a>  ";
            }
            if ($current_page>$max_page_links/2){//Are we going far away from the first viewed page link?
                if (ceil($num_stuff/$max)-$current_page<(($max_page_links/2)+1)){//Are we getting closer to last viewed page link?
                    $start_counter=$current_page-($max_page_links-(ceil($num_stuff/$max)-$current_page));//Yes, Then we need to view more page links
                    $end_counter=ceil($num_stuff/$max);//And no need to view page links more than the query can bring
                }else{
                    $start_counter=$current_page-(($max_page_links/2)-1);//No, then just view some links before the currentrent page
                    $end_counter=$current_page+($max_page_links/2);//And some links after
                }
            }
            else{//Still in the first pages?
                $start_counter=1;//Start with page one
                $end_counter=$max_page_links;//Show only enough links
            }
            for ($i=$start_counter;$i<=$end_counter;$i++){//A loop for viewing the links
                if ($i==$end_counter){//Is this the last link?
                    if ($i==$current_page){//Are we actually on the last page? Because we don't need the | after the link
                        echo "<a style=\"color:blue;\" class=\"link\">".$i."</a>";//Then make it look like we're on that page
                    }else{
                        echo "<a class=\"link\" href=\"".$page_link."page=".$i."\">".$i."</a>";//Well yeah, it's the last link.. but we're not there yet.
                    }
                }else{//Not the last page you say.. mmm.. then print normally (with | after the link)
                    if ($i==$current_page){//Are we vewing this page?
                        echo "<a style=\"color:blue;\" class=\"link\">".$i."</a>  |  ";//Make us know it
                    }else{//Not viewing.. just a normal link (the most common case here)
                        echo "<a class=\"link\" href=\"".$page_link."page=".$i."\">".$i."</a>  |  ";//Nothing to say
                    }
                }
            }
            if ($current_page<ceil($num_stuff/$max)){//Making the next and last page links
                $next_page=$current_page+1;//Next means +1
                $last_page=ceil($num_stuff/$max);//and the last page is the page.. whell.. it's the last one the query can bring
                echo "  <a style=\"text-decoration: none;\" href=\"".$page_link."page=$next_page\">>></a>";
                echo "  <a style=\"text-decoration: none;\" href=\"".$page_link."page=$last_page\">>|</a>";
            }
}
}
Gewalop 1 Newbie Poster
epicrevolt 6 Junior Poster in Training

I am testing right now. If it works for me you are my god! Thank you so much for this!!! I have been working for hours trying to get a pagination script working and here you are just spilling out the answer right in front of me. THANK YOU!

Line 33 needs to be changed from:

echo "<a style=\"text-decoration: none;\" href=\"".$page_link."page=$previous_page\"<<</a>  ";

to this... you didn't close the link:

echo "<a style=\"text-decoration: none;\" href=\"".$page_link."page=$previous_page\"><</a>  ";
epicrevolt 6 Junior Poster in Training

By the way, is there a way to limit the pagination if you have less than x amount of pages? Like if I want it to eventually display a max of 10 pages, but I only have 3 pages filled up right now, is there a way to make it only show the max if you have at least that many pages?

Gewalop 1 Newbie Poster

@epicrevolt: well I've looked hard for a script that can do what I wanted, I was only able to find the first part, but I have lots of rows.. so I ended up with 120 numbered links at the end of each page.. so I decided to write one from scratch.. the minute I added this to my project I posted it, so I'm glad it was useful to you.

About your question, put the leave everything the way you want it, max rows per page and max links per page.
After the line 62 add a new "for loop" for 7 more numbers and make them linkless (no "a" tag) and you're good to go.

epicrevolt 6 Junior Poster in Training

Could you please elaborate on the for loop? I am kinda new to PHP and I suck at for and foreach loops :(

Gewalop 1 Newbie Poster

just after the line 62

<?php
for ($i=3;$i<8;$i++){
echo "<a class=\"link\" href=\"#\">".$i."</a>  |  "
}
?>

I guess it's easy

tomato.pgn -6 Posting Whiz in Training

i think so u made this script quiet complicated for php beginners....
I will soon post the easier solution to this ...might be in tomorrow evening....
i have worked many times in this type of pagings...

tomato.pgn -6 Posting Whiz in Training

this is the solution to ur problem...if u want elaboration then i will explain u in another post....waiting for ur reply whether it was helpful.....

<?php
$page=1;
$nor=5;
$a=1;
if(isset($_GET['page']))
{
}
else
{
$_GET['page']=1;
}
echo $_GET['page'];
$con=mysql_connect("localhost","root","")
or die ("error");
$db=mysql_select_db("check",$con)
or die("database not found");
$result=mysql_query("SELECT * FROM comment")
or die ("query error");
echo "<table border='1'><tr><th>name</th><th>Comment</th></tr>";
$r=mysql_num_rows($result);
echo $r."<br/>";
$p=ceil($r/$nor);
//echo $p;
while($rows=mysql_fetch_array($result))
{
if($a>($_GET['page']-1)*$nor)
{
echo "<tr><td>".$rows['user']."</td><td>".$rows['comment']."</td></tr>";
}
$a=$a+1;
}
echo "</table>";
for($i=1;$i<=$p;$i++)
{
if($i==$_GET['page'])
{
echo $i;
}
else
{
echo "<a href='check.php?page=".$i."'>".$i."</a>";
}
}

?>
IIM commented: thanks for small n sweet script!!! +0
Katie138 commented: Hi, thank you for posting this code, I am very new to PHP, I just have one query, when I use this code it seems to just reduce the amount of records shown per page, do you know where I've gone wrong? Any help would be appreciated! +0
tomato.pgn -6 Posting Whiz in Training

if u want a more advanced paging system then i will make it for u within an hour.....just waiting what else u want frm this post.....

mohammed001 0 Newbie Poster

hello

(Fully Fixed version of the function)

if you use this function to paginate mysql results you'll find it good in all cases but if your query results will be shorter than the maximum page links which is '$max_page_links' you'll have useless page links which appointed in line 46 '$end_counter=$max_page_links;//Show only enough links' so you'll need to fix it by changing '$end_counter=$max_page_links;//Show only enough links' to '$end_counter = ceil($total/$max);', but this will cause mass-error it will make all of your links appear if you have more pages than the '$max_page_links' variable so..

you have to replace line 44,45,46

which is

else{//Still in the first pages?
$start_counter=1;//Start with page one
$end_counter=$max_page_links;//Show only enough links
}
with this
else { //Still in the first pages?
    $start_counter = 1; //Start with page one

    if(ceil($num_stuff/$max)-$current_page < (($max_page_links/2)+1)){
        $end_counter = ceil($num_stuff/$max); //Show only enough links
    } else {
        $end_counter = $max_page_links; //Show only enough links
    }
}

also I've modified the 'echo' function for the links output to push it into '$nav' variable and then return it which make it more stronger if don't wish to use this as a function and want to put it any place in your code then print out the '$nav' variable where you want to render your links.

Important Note: I've fully changed alot of variable names so if you want to use part of my function to replace it with a part of the orignal function it won't work so you must use any of them not to mix them.

this is the full function after my modifications
//Preparing --Start--
//comment the following function link to avoid using it as a function and don't forget to comment the closing of it--
function pageThis($max, $max_page_links, $query, $page_link){
    // -- and Uncomment the next 4 lines if don't wish to use this as a function
    //$page_link = "paged.php";
    //$max = 30;//Maximum items per page (rows)
    //$max_page_links = 10;//Maximum links number in the page
    //$sql .= "select * from some_table";//Your query

    //Getting the total possible rows
    $total = mysql_num_rows(mysql_query($sql));
    if(isset($_GET['page'])&&$_GET['page']>0){
        //Now the page number make more sense (page=1 is actually the first page)
        $start = intval($_GET['page'])-1;
        //Some cleaning (SQL Injection prevention, and get rid of negative numbers)
        $current = intval($_GET['page']);
    //If no parameters passed.. just give the first page
    } else {
        $current = 1;
        $start = 0;
    }
    //If a large page numbre passed (more than there actually is) just give the last page
    if($current > ceil($total/$max)){
        $current = ceil($total/$max);
        $start = ceil($total/$max)-1;
    }
    //Which row to start with
    $start *= $max;
    //Adding the limit
    //$sql .= " LIMIT '".$start."', '".$max;
    //Preparing --End--

    //Actual paging --Start--
    //Is there any need for pagin?
    if($total > $max){
        //Making previous page & first page links when needed
        if($current > 1){
            //previousious means -1
            $prev = $current-1;
            //First page is the page number.. you guessed it right.. 1
            $nav .="<a href='".$page_link."?page=1'>first</a>  ";
            $nav .="<a href='".$page_link."?page=".$prev."'> << </a>  ";
        }
        //Are we going far away from the first viewed page link?
        if($current > $max_page_links/2){
            //Are we getting closer to last viewed page link?
            if(ceil($total/$max)-$current < (($max_page_links/2)+1)){
                //Yes, Then we need to view more page links
                $start_counter = $current-($max_page_links-(ceil($total/$max)-$current));
                //And no need to view page links more than the query can bring
                $end_counter = ceil($total/$max);
                //echo "case: 1";
            } else {
                //No, then just view some links before the currentrent page
                //echo "case: 2";
                $start_counter = $current-(($max_page_links/2)-1);
                //And some links after
                $end_counter = $current+($max_page_links/2);
            }
            //Still in the first pages?
        } else {
            //Start with page one
            $start_counter = 1;
            if(ceil($total/$max)-$current < (($max_page_links/2)+1)){
                //echo "case: 4";
                //Show only enough links
                $end_counter = ceil($total/$max);
            } else {
                //echo "case: 5";
                //Show only enough links
                $end_counter = $max_page_links;             
            }
        }
        //A loop for viewing the links
        for($i=$start_counter;$i<=$end_counter;$i++){
            //Is this the last link?
            if($i == $end_counter){
                //Are we actually on the last page? Because we don't need the | after the link
                if($i == $current){
                    //Then make it look like we're on that page
                    $nav .= "<a style='background:#3399CC;'>".$i."</a>";
                } else {
                    //Well yeah, it's the last link.. but we're not there yet.
                    $nav .= "<a href='".$page_link."?page=".$i."'>".$i."</a>";
                }
            //Not the last page you say.. mmm.. then print normally (with | after the link)
            } else {
                //Are we vewing this page?
                if($i == $current){
                    //Make us know it
                    $nav .= "<a style='background:#3399CC;'>".$i."</a>";
                //Not viewing.. just a normal link (the most common case here)
                } else {
                    //Nothing to say
                    $nav .= "<a href='".$page_link."?page=".$i."'>".$i."</a>";
                }
            }
        } // Loop Ending
        //Making the next and last page links
        if($current<ceil($total/$max)){
            //Next means +1
            $next_page = $current+1;
            //and the last page is the page.. whell.. it's the last one the query can bring
            $last_page=ceil($total/$max);
            $nav .= "  <a href='".$page_link."?page=".$next_page."'> >> </a>";
            $nav .= "  <a href='".$page_link."?page=".$last_page."'>last</a>";
        }
    }
    // comment the follwing 2 lines if you commented the function line at the top
   return $nav;
}
mohammed001 0 Newbie Poster
(Fully Fixed version of the function) + CSS for the pagenation Div

now I add some CSS staff to make it looks better

this is the full function after my modifications
//Preparing --Start--
//comment the following function link to avoid using it as a function and don't forget to comment the closing of it--
function pageThis($max, $max_page_links, $query, $page_link){
    // -- and Uncomment the next 4 lines if don't wish to use this as a function
    //$page_link = "paged.php";
    //$max = 30;//Maximum items per page (rows)
    //$max_page_links = 10;//Maximum links number in the page
    //$sql .= "select * from some_table";//Your query

    //Getting the total possible rows
    $total = mysql_num_rows(mysql_query($sql));
    if(isset($_GET['page'])&&$_GET['page']>0){
        //Now the page number make more sense (page=1 is actually the first page)
        $start = intval($_GET['page'])-1;
        //Some cleaning (SQL Injection prevention, and get rid of negative numbers)
        $current = intval($_GET['page']);
    //If no parameters passed.. just give the first page
    } else {
        $current = 1;
        $start = 0;
    }
    //If a large page numbre passed (more than there actually is) just give the last page
    if($current > ceil($total/$max)){
        $current = ceil($total/$max);
        $start = ceil($total/$max)-1;
    }
    //Which row to start with
    $start *= $max;
    //Adding the limit
    //$sql .= " LIMIT '".$start."', '".$max;
    //Preparing --End--

    //Actual paging --Start--
    //Is there any need for pagin?
    if($total > $max){
        //Making previous page & first page links when needed
        if($current > 1){
            //previousious means -1
            $prev = $current-1;
            //First page is the page number.. you guessed it right.. 1
            $nav .="<a href='".$page_link."?page=1'>first</a>  ";
            $nav .="<a href='".$page_link."?page=".$prev."'> << </a>  ";
        }
        //Are we going far away from the first viewed page link?
        if($current > $max_page_links/2){
            //Are we getting closer to last viewed page link?
            if(ceil($total/$max)-$current < (($max_page_links/2)+1)){
                //Yes, Then we need to view more page links
                $start_counter = $current-($max_page_links-(ceil($total/$max)-$current));
                //And no need to view page links more than the query can bring
                $end_counter = ceil($total/$max);
                //echo "case: 1";
            } else {
                //No, then just view some links before the currentrent page
                //echo "case: 2";
                $start_counter = $current-(($max_page_links/2)-1);
                //And some links after
                $end_counter = $current+($max_page_links/2);
            }
            //Still in the first pages?
        } else {
            //Start with page one
            $start_counter = 1;
            if(ceil($total/$max)-$current < (($max_page_links/2)+1)){
                //echo "case: 4";
                //Show only enough links
                $end_counter = ceil($total/$max);
            } else {
                //echo "case: 5";
                //Show only enough links
                $end_counter = $max_page_links;             
            }
        }
        //A loop for viewing the links
        for($i=$start_counter;$i<=$end_counter;$i++){
            //Is this the last link?
            if($i == $end_counter){
                //Are we actually on the last page? Because we don't need the | after the link
                if($i == $current){
                    //Then make it look like we're on that page
                    $nav .= "<a class='current'>".$i."</a>";
                } else {
                    //Well yeah, it's the last link.. but we're not there yet.
                    $nav .= "<a href='".$page_link."?page=".$i."'>".$i."</a>";
                }
            //Not the last page you say.. mmm.. then print normally (with | after the link)
            } else {
                //Are we vewing this page?
                if($i == $current){
                    //Make us know it
                    $nav .= "<a class='current'>".$i."</a>";
                //Not viewing.. just a normal link (the most common case here)
                } else {
                    //Nothing to say
                    $nav .= "<a href='".$page_link."?page=".$i."'>".$i."</a>";
                }
            }
        } // Loop Ending
        //Making the next and last page links
        if($current<ceil($total/$max)){
            //Next means +1
            $next_page = $current+1;
            //and the last page is the page.. whell.. it's the last one the query can bring
            $last_page=ceil($total/$max);
            $nav .= "  <a href='".$page_link."?page=".$next_page."'> >> </a>";
            $nav .= "  <a href='".$page_link."?page=".$last_page."'>last</a>";
        }
    }
    // comment the follwing 2 lines if you commented the function line at the top
   return $nav;
}
the CSS
.pagination a{
    float:left; /* Change this to right if arabic sites */
    color:#0A7EC5;
    display:block;
    min-width:18px;
    text-align:center;
    border:solid 1px #8DC5E6;
    border-radius:3px; 
    -moz-border-radius:3px;
    -webkit-border-radius:3px;
    padding:6px 4px 6px 4px;
    margin-right: 2px;
    background:#F8FCFF;
}


.pagination a:hover, .pagination a.current, .pagination a:active, .pagination a:focus{  
  color:#FFFFFF;
  border-color:#3390CA;
  text-decoration:none;
  box-shadow:0px 1px #EDEDED;
  -moz-box-shadow:0px 1px #EDEDED;
  -webkit-box-shadow:0px 1px #EDEDED;
  text-shadow:0px 1px #388DBE;
  background:#58B0E7;
  background:-moz-linear-gradient(top,#B4F6FF 1px,#63D0FE 1px,#58B0E7);
  background:-webkit-gradient(linear,0 0,0100%,color-stop(0.02,#B4F6FF),color-stop(0.02,#63D0FE),color-stop(1,#58B0E7));}
mohammed001 0 Newbie Poster

Sorry I forgot to define $nav in the beginning so please edit my two posts and put this code after line 9

$nav = "";
Member Avatar for diafol
diafol

How about correcting it and re-posting?

mohammed001 0 Newbie Poster

better if you allow me to edit my posts or just let as it is .. not bad and just let the people fix it as i said by adding $nav = ""; after line 9
thanks

Member Avatar for diafol
diafol

leave it then. ok.

Cocodix 0 Newbie Poster

please help me to cull a function wich is function.php
Thank you

Member Avatar for diafol
diafol

Don't hijack a dead thread and please supply all the information required to help you. Start a new thread if you can't find what you need from the search facility.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.