Working PHP Pagination Function

Are you looking for PHP pagination function? here one slick PHP function that will paginate your database records. You can easily combine this function in your project to paginate your database records. Just drop the function within your PHP script and call it wherever you’ll need the pagination.

pagination_php
Pagination links will look similar to picture above, as you can see I have added some CSS to style the links, and below you will find the whole pagination function, which you can copy into your projects.

PHP
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364

function paginate($item_per_page, $current_page, $total_records, $total_pages, $page_url)
{
    $pagination = '';
    if($total_pages > 0 && $total_pages != 1 && $current_page <= $total_pages){ //verify total pages and current page number
        $pagination .= '

<ul class="pagination">';
        $right_links    = $current_page + 3;
        $previous       = $current_page - 3; //previous link
        $next           = $current_page + 1; //next link
        $first_link     = true; //boolean var to decide our first link
        if($current_page > 1){
			$previous_link = ($previous==0)?1:$previous;
            $pagination .= '
<li class="first"><a href="'.$page_url.'?page=1" title="First">&laquo;</a></li>
'; //first link
            $pagination .= '
<li><a href="'.$page_url.'?page='.$previous_link.'" title="Previous">&lt;</a></li>
'; //previous link
                for($i = ($current_page-2); $i < $current_page; $i++){ //Create left-hand side links
                    if($i > 0){
                        $pagination .= '
<li><a href="'.$page_url.'?page='.$i.'">'.$i.'</a></li>
';
                    }
                }
            $first_link = false; //set first link to false
        }
        if($first_link){ //if current active page is first link
            $pagination .= '
<li class="first active">'.$current_page.'</li>
';
        }elseif($current_page == $total_pages){ //if it's the last active link
            $pagination .= '
<li class="last active">'.$current_page.'</li>
';
        }else{ //regular current link
            $pagination .= '
<li class="active">'.$current_page.'</li>
';
        }
        for($i = $current_page+1; $i < $right_links ; $i++){ //create right-hand side links
            if($i<=$total_pages){
                $pagination .= '

<li><a href="'.$page_url.'?page='.$i.'">'.$i.'</a></li>
';
            }
        }
        if($current_page < $total_pages){ 
				$next_link = ($i > $total_pages)? $total_pages : $i;
                $pagination .= '
<li><a href="'.$page_url.'?page='.$next_link.'" >&gt;</a></li>
'; //next link
                $pagination .= '
<li class="last"><a href="'.$page_url.'?page='.$total_pages.'" title="Last">&raquo;</a></li>
'; //last link
        }
        $pagination .= '</ul>
';
    }
    return $pagination; //return pagination links
}

Usage

Just pass few arguments to the function. Group of links, current page number, total database records and page url. You will need to get total records of database and current page number of the page from URL.

PHP
12345678910111213141516171819202122232425262728293031323334353637383940414243444546

<?php
$db_username        = 'root'; //database username
$db_password        = ''; //dataabse password
$db_name            = 'test'; //database name
$db_host            = 'localhost'; //hostname or IP
$item_per_page      = 5; //item to display per page
$page_url 			= "http://localhost/ajax-pagination/";

$mysqli_conn = new mysqli($db_host, $db_username, $db_password,$db_name); //connect to MySql
if ($mysqli_conn->connect_error) { //Output any connection error
    die('Error : ('. $mysqli_conn->connect_errno .') '. $mysqli_conn->connect_error);
}
if(isset($_GET["page"])){ //Get page number from $_GET["page"]
    $page_number = filter_var($_GET["page"], FILTER_SANITIZE_NUMBER_INT, FILTER_FLAG_STRIP_HIGH); //filter number
    if(!is_numeric($page_number)){die('Invalid page number!');} //incase of invalid page number
}else{
    $page_number = 1; //if there's no page number, set it to 1
}
$results = $mysqli_conn->query("SELECT COUNT(*) FROM paginate"); //get total number of records from database
$get_total_rows = $results->fetch_row(); //hold total records in variable
$total_pages = ceil($get_total_rows[0]/$item_per_page); //break records into pages
################# Display Records per page ############################
$page_position = (($page_number-1) * $item_per_page); //get starting position to fetch the records
//Fetch a group of records using SQL LIMIT clause
$results = $mysqli_conn->query("SELECT id, name, message FROM paginate ORDER BY id ASC LIMIT $page_position, $item_per_page");
//Display records fetched from database.
echo '
<ul class="contents">';
while($row = $results->fetch_assoc()) {
    echo '
<li>';
    echo  $row["id"]. '. <strong>' .$row["name"].'</strong> &mdash; '.$row["message"];
    echo '</li>
';
}
echo '</ul>
';
################### End displaying Records #####################
//create pagination
echo '
<div align="center">';
// We call the pagination function here.
echo paginate($item_per_page, $page_number, $get_total_rows[0], $total_pages, $page_url);
echo '</div>
';

CSS

Here’s CSS you will need to make your pagination links pretty.

CSS
123456789101112131415161718192021222324252627282930
.pagination{
	margin:0;
	padding:0;
}
.pagination li{
	display: inline;
	padding: 6px 10px 6px 10px;
	border: 1px solid #ddd;
	margin-right: -1px;
	font: 13px/20px Arial, Helvetica, sans-serif;
	background: #FFFFFF;
}
.pagination li a{
	text-decoration:none;
	color: rgb(89, 141, 235);
}
.pagination li.first {
	border-radius: 5px 0px 0px 5px;
}
.pagination li.last {
	border-radius: 0px 5px 5px 0px;
}
.pagination li:hover{
	background: #EEE;
}
.pagination li.current {
	background: #89B3CC;
	border: 1px solid #89B3CC;
	color: #FFFFFF;
}

Below is the link to gist if you want to see whole implementation of this function.
View & Download Gist File

  • 13 Comments

    Add Comment
    • Kleidi
      Thank you for the great functions. With some minor modifications (some reported previosly by others), it works great. What i will add, except the ones commented by others, is regarding the filtering if the page is number. You don;t have to end the script if is not numeric, but you can clean the request easly. So, this part:
      12
      $page_number = filter_var($_GET[&quot;page&quot;], FILTER_SANITIZE_NUMBER_INT, FILTER_FLAG_STRIP_HIGH); //filter number
          if(!is_numeric($page_number)){die(&#039;Invalid page number!&#039;);} //incase of invalid page number
      ...can be modified as follows: $page_number = mysqli_real_escape_string($conn,preg_replace('/[^0-9]/', '', $_GET["page"])); //clean the reques by replacing everything except numbers You can clean it also by not using mysqli_real_escape_string() function by just using preg_replace, too, if you will not pass it to db. I prefer to use as I stated on before. This way, your request will be cleaned (every time will be number) and your script can continue to show the results. Hope it was helpful for everyone.
    • Heiberlin
      Best pagination function ever! Thanks a million!
    • Yunus Emre Uzun
      Thanks for the function it's really helpful but there is something wrong with the $previous variable. It should be like this; $previous = $current_page - 1;
    • Abhi
      sir how to change "?page=" that field i want only "/"
    • Javed Ur Rehman
      Hi Saran, I really found your tutorial very helpful and good. I also recently wrote a tutorial about it, i hope you will also find it helpful, i will be glad if you also share your reviews. https://www.allphptricks.com/create-simple-pagination-using-php-and-mysqli/
    • Ruzeen
      Changed these variables to get rid of the -1 error $previous_link = $current_page-1; $next_link = $current_page+1;
    • Bbb
      `products` ( `id` int(11) NOT NULL AUTO_INCREMENT, `product_code` varchar(60) NOT NULL, `product_name` varchar(60) NOT NULL, `product_desc` tinytext NOT NULL, `product_img_name` varchar(60) NOT NULL, `price` decimal(10,2) NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `product_code` (`product_code`) ) AUTO_INCREMENT=1 ;
    • Marcello
      The download link is broken. Can you fix it ? Or can someone share it ?
    • Morte
      i have noticed there was a error in the script: it always gave -1 for last page. instead of what the last page should of been. so i changed them to $current_page - 1 or $current_page + 1; error:
      123
      $previous_link = ($previous==0)?1:$previous;
      
      $next_link = ($i > $total_pages)? $total_pages : $i;
      new code:
      1234567891011121314151617181920212223242526272829303132333435363738394041424344454647
      function paginate($item_per_page, $current_page, $total_records, $total_pages, $page_url)
      {
      	
          $pagination = '';
          if($total_pages > 0 && $total_pages != 1 && $current_page <= $total_pages){ //verify total pages and current page number
              $pagination .= '<ul class="pagination">';
             
               $right_links    = $current_page + 3;
              $previous       = $current_page - 3; //previous link
              $next           = $current_page + 1; //next link
              $first_link     = true; //boolean var to decide our first link
             
              if($current_page > 1){
                  $previous_link = $current_page - 1;
                  $pagination .= '<li class="first"><a href="'.$page_url.'?page=1" title="First">&laquo;</a></li>'; //first link
                  $pagination .= '<li><a href="'.$page_url.'?page='.$previous_link.'" title="Previous">&lt;</a></li>'; //previous link
                      for($i = ($current_page-2); $i < $current_page; $i++){ //Create left-hand side links
                          if($i > 0){
                              $pagination .= '<li><a href="'.$page_url.'?page='.$i.'">'.$i.'</a></li>';
                          }
                      }  
                  $first_link = false; //set first link to false
              }
             
              if($first_link){ //if current active page is first link
                  $pagination .= '<li class="active"><a>'.$current_page.'</a></li>';
              }elseif($current_page == $total_pages){ //if it's the last active link
                  $pagination .= '<li class="active"><a>'.$current_page.'</a></li>';
              }else{ //regular current link
                  $pagination .= '<li class="active"><a>'.$current_page.'</a></li>';
              }
                     
              for($i = $current_page+1; $i < $right_links ; $i++){ //create right-hand side links
                  if($i<=$total_pages){
                      $pagination .= '<li><a href="'.$page_url.'?page='.$i.'">'.$i.'</a></li>';
                  }
              }
              if($current_page < $total_pages){
                      $next_link = $current_page + 1;
                      $pagination .= '<li><a href="'.$page_url.'?page='.$next_link.'" >&gt;</a></li>'; //next link
                      $pagination .= '<li class="last"><a href="'.$page_url.'?page='.$total_pages.'" title="Last">&raquo;</a></li>'; //last link
              }
             
              $pagination .= '</ul>';
          }
          return $pagination; //return pagination links
      }
      this is so people can use the proper script for pagination. Good idea tho