Feed on
Posts
Comments

In the years that I’ve been a web developer, I have written very few OOP PHP scripts. I just haven’t had the need to, and to be honest the whole OOP concept seemed like something I didn’t need to bother with. Why do I need to write a script in an object-oriented style and how will it help me? I had seen examples and read tutorials about OOP (some horribly bad and some really good) but never had any desire to try it myself until one day when I was working on a couple of different projects that both needed the same thing, pagination.

Pagination just means numbering pages. In the project that I was working on, I was retrieving large amounts of data from a MySQL database and realized that I would have to break the data up into pages for two main reasons, 1) there was so much data that it could hang the browser when it was loading and 2) from a user perspective (we still care about that right?) it was unruly to say the least. If I was returning 50,000 rows from a database query, I knew that I would need to slice that up into more manageable chunks. Now in the past, I had written basic pagination functions to handle this type of issue and sometimes copied and pasted functions from older scripts to cut down on development time, fixing and re-coding where necessary. But I realized that for this new project I could try to write a pagination class that I would be able to just plug into any script and have it do the pagination for me. I could write a pagination class that I could use for my projects and future projects, and learn OOP in the process. I love killing two birds with one stone.

Which brings me to our pagination class (paginator.class.php). Now I’m not claiming to be the first person to write a pagination class — far from it. But I do feel that this one is the most lightweight, feature-rich, and easy to use that I’ve seen. For an example of the pagination class in action, click here.

To download the pagination class, click here.

Update (Aug 4, 2009): Some of you have asked for more examples of the PHP pagination class I wrote, specifically the same examples I’m using here on the site. The database comes from MySQL’s free example databases available at http://dev.mysql.com/doc/#sampledb (my example uses the world database). The two examples I use here can be seen at http://www.catchmyfame.com/paginator/example.php and http://www.catchmyfame.com/paginator/example-form.php. You can download both PHP files in a zip file. You’ll need to setup the database yourself and fill in the example PHP files with your database info. Don’t forget to grab the sample database from MySQL.

Update (Oct 25, 2011): Version 2 now available for download. See here for more info. Note that the examples on this page still use an older version of the class.

In the example below, you can see the paginator used at the top and bottom of the database query.

In this example, you can see the mid range property which creates a range of pages around the current page and the use of … to distinguish the break between contiguous pages

In this example you can see the optional items per page drop down menu

In this example you can see the optional page jump menu

In this example we see how the previous and next buttons are sensitive to what the current page is.

This example shows how when there are less than 11 pages to display that the previous, next, and all links are not shown

This example shows an alternate styling of the pagination results. By default a Digg-like CSS scheme is used however you can style the menu in limitless ways


Paginator.class.php

The paginator class allows you to easily generate page numbers and restrict database results without having to create complex pagination code of your own.

Features:

  • Easy to use and reuse.
  • Dynamically creates page numbers based on the total number of items in a query and the desired number of items per page.
  • Ability to select a number of pages to display around the currently select page.
  • Links to show all results instead of paginated results.
  • Easily styled via CSS.
  • Returns SQL which can be used to modify the results in query.
  • The items per page can be changed by the user using a build in method which generates a simple drop down menu.
  • A ‘jump to page’ menu can be generated to give the user quick access to jump to any page of the results.
  • Creates ‘previous’ and ‘next’ buttons when more than 10 pages are generated.

Properties:

  • $items_per_page – The desired number of items to be shown on a page. If you use this and the display_items_per_page method at the same time, it will override anything the user chooses from the drop down menu created by display_items_per_page.
  • $items_total – The total number of items you’ll be paginating. Typically set by querying a table for a count of rows.
  • $current_page – The page the user is viewing. Will always be an integer >= 1.
  • $num_pages – The total number of pages as generated by the paginator method.
  • $mid_range – The number of pages to show ‘around’ the current page. See step 5 in How To Use below.
  • $low – The offset to use in a SQL LIMIT statement (e.g. SELECT * FROM employees LIMIT 20,10).
  • $high – The number of rows to select in a SQL LIMIT statement (e.g. SELECT * FROM employees LIMIT 20,10).
  • $limit – A string used in an SQL statement to automatically handle the limiting of results based on the current page of results.
  • $return – A string used to store the HTML containing the page numbers.Used in the display_pages method.
  • $default_ipp = 25 – The default number of items to display per page.

Methods:

  • Paginator. Constructor. Usage: $pages = new Paginator;
  • paginate. Calculates pages to display. Usage: $pages->paginate();
  • display_items_per_page. Returns a string of HTML used to display an items per page menu. Usage: echo  $pages->display_items_per_page();
  • display_jump_menu. Returns a string of HTML used to display a page jump menu. Usage: echo $pages->display_jump_menu();
  • display_pages. Returns a string of HTML used to display the pages generated by the paginator
    method. Usage: echo $pages->display_pages();

How to use:

  1. Include paginator.class.php at the top of your scriptrequire_once 'paginator.class.php';Note: You could use include(), include_once(), or require() however using require_once ensures that the class will only be included once and if it can’t be found, will cause a fatal error.
  2. Set the total number of items that you’ll be paginating.There are two ways to do this, 1) you can hard code the total, but that’s unrealistic since you’ll probably be using this class to paginate a database anyway (the whole point no?) but it can be a convenient way of testing or 2) make a quick call to your database to count the items you’ll be paginating. Ex: ‘SELECT COUNT(*) FROM table’ and save the total in a variable for use in step 4.$pages->items_total = $num_rows;
  3. Create a new Paginator object.$pages = new Paginator;
  4. Set the total items property of this new Paginator object.$pages->items_total = X where X is the total from step 2
  5. Set the mid range property.The mid range is the number of pages that the paginator will display, centered around and including the selected page. For example, if the mid range is set to seven ($pages->mid_range = 7;) then when browsing page 50 of 100, the mid range generates links to pages 47, 48, 49, 50, 51, 52, and 53. The mid range moves in relation to the selected page. If the user is at either the low or high end of the list of pages, it will slide  the range toward the other side to accommodate the position. For example, if  the user visits page 99 of 100, the mid range will generate links for pages  94, 95, 96, 97, 98, 99, and 100.$pages->mid_range = X; where X is odd and >=3. The default mid_range property is 7.
  6. That’s all for the configuration, now you can generate page numbers. To paginate, call the pagination method ($pages->paginate();). This generates no output so to show the page numbers call the display method ($pages->display_pages();).
    You MUST call the paginate method before calling the display method. You can call the display method more than once which can be handy for display page numbers both above and below a result set.echo $pages->display_pages();
  7. Optionally, you can give the visitor features in addition to what is provided by the display method.
    1. A drop down page jump menu is available via the display_jump_menu method (echo $pages->display_jump_menu();). This is a simple select menu that lists all page numbers. When a user changes the page number, the page will automatically switch to the selected page.
    2. A drop down items per page menu is available via the display_items_per_page method(echo $pages->display_items_per_page();). This select menu allows visitors to change the number of items that are displayed on a page. By default, the list it generates is 10, 25, 50, 100, All. You can modify the class if needed to allow for other options however the All options is case-sensitive. Note that the drop down menu that this creates will not work if you also set the $items_per_page property. Using both at the same time doesn’t really make sense anyway
  8. Once the paginate method has been called (see step 6), you can execute your db query to fetch the limited result set (or all results). Paginate creates the SQL used to limit results automatically so you can edit your query to take advantage of this. For example, if your query before pagination was SELECT id, name, address FROM table ORDER BY id ASC you would change it to be SELECT id, name, address FROM table ORDER BY id ASC $pages->limitWhen a user selects the ‘All’ option, they effectively set $pages->limit to nothing and any page selected automatically creates the appropriate limit.
    $pages->limit
  9. Styles. The pagination class has been created so that it can be styles with CSS easily. The recommended CSS is<style type="text/css">
    .paginate {
    font-family: Arial, Helvetica, sans-serif;
    font-size: .7em;
    }
    a.paginate {
    border: 1px solid #000080;
    padding: 2px 6px 2px 6px;
    text-decoration: none;
    color: #000080;
    }
    a.paginate:hover {
    background-color: #000080;
    color: #FFF;
    text-decoration: underline;
    }
    a.current {
    border: 1px solid #000080;
    font: bold .7em Arial,Helvetica,sans-serif;
    padding: 2px 6px 2px 6px;
    cursor: default;
    background:#000080;
    color: #FFF;
    text-decoration: none;
    }
    span.inactive {
    border: 1px solid #999;
    font-family: Arial, Helvetica, sans-serif;
    font-size: .7em;
    padding: 2px 6px 2px 6px;
    color: #999;
    cursor: default;
    }
    </style>
  10. Basic example:<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN”
    “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>
    <html xmlns=”http://www.w3.org/1999/xhtml”>
    <head>
    <meta http-equiv=”Content-Type” content=”text/html; charset=iso-8859-1? />
    <title>Paginator</title>
    <style type=”text/css”>
    .paginate {
    font-family: Arial, Helvetica, sans-serif;
    font-size: .7em;
    }
    a.paginate {
    border: 1px solid #000080;
    padding: 2px 6px 2px 6px;
    text-decoration: none;
    color: #000080;
    }
    a.paginate:hover {
    background-color: #000080;
    color: #FFF;
    text-decoration: underline;
    }
    a.current {
    border: 1px solid #000080;
    font: bold .7em Arial,Helvetica,sans-serif;
    padding: 2px 6px 2px 6px;
    cursor: default;
    background:#000080;
    color: #FFF;
    text-decoration: none;
    }
    span.inactive {
    border: 1px solid #999;
    font-family: Arial, Helvetica, sans-serif;
    font-size: .7em;
    padding: 2px 6px 2px 6px;
    color: #999;
    cursor: default;
    }
    </style>
    </head>
    <body>
    <?php
    require_once ‘paginator.class.php’;
    // Make your database connection here and retrieve your total number of
    items (i.e. SELECT COUNT(*) FROM…)
    $pages = new Paginator;
    $pages->items_total = $db_count;
    $pages->mid_range = 7;
    $pages->paginate();echo $pages->display_pages();
    // Make your db query here. Include $pages->limit as described in step 8.
    (i.e. SELECT id,fname,lname FROM employees $pages->limit)
    echo $pages->display_pages(); // Optional call which will display the page numbers after the results.
    echo $pages->display_jump_menu(); // Optional – displays the page jump menu
    echo $pages->display_items_per_page(); //Optional – displays the items per
    page menu
    ?>
    </body>
    </html>

All in all you could add pagination to any database driven set of results with about five lines of code. To display the current page number in the format ‘Page X of Y’ where X is the current page and Y is the total number of pages, use the code:

echo "<p class=\"paginate\">Page: $pages->current_page of $pages->num_pages</p>\n";

To display the SQL that was generated, use the code:

echo "<p class=\"paginate\">SELECT * FROM table $pages->limit (retrieve
records $pages->low-$pages->high from table - $pages->items_total item total / $pages->items_per_page
items per page)";

265 Responses to “Finally, the simple pagination class”

  1. shulato says:

    thanks! i will implement this. web development

  2. V says:

    I tried to integrate pagination in a script I have but I keep getting errors. Can someone please help? I pasted my code at http://www.phpriot.com/2918
    When I try the script I get,
    Warning: mysql_num_rows() expects parameter 1 to be resource, boolean given in C:\wamp\www\gisttest\comments.php on line 97
    Notice: Undefined index: ipp in C:\wamp\www\gisttest\paginator.class.php on line 25
    Notice: Undefined index: page in C:\wamp\www\gisttest\paginator.class.php on line 35
    Notice: Undefined index: ipp in C:\wamp\www\gisttest\paginator.class.php on line 100
    Notice: Undefined index: ipp in C:\wamp\www\gisttest\paginator.class.php on line 101
    All Database query failed: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ‘-25,25′ at line 1

    • shulato says:

      move this
      $comments_table = mysql_query(“SELECT COUNT(*) FROM comments WHERE post_id=’$post_id’ ORDER BY id ASC $pages->limit”, $connection);
      if (!$comments_table) {
      die(“Database query failed: ” .mysql_error());
      }

      at the top of

      $num_rows = mysql_num_rows($db_select);
      $pages = new Paginator;
      $pages->items_total = $num_rows[0];
      $pages->mid_range = 9;
      $pages->paginate();
      echo $pages->display_pages();

      then replace
      $num_rows = mysql_num_rows($db_select);
      into this
      $num_rows = mysql_num_rows($comments_table);

  3. Jaye Chan says:

    this is the most elegant pagination scripts i’ve ever found.. many thanks and more power to the developer of this class

  4. nik mauro says:

    it is possible to hide the “”All”" btn?

  5. Jeff says:

    Do you have a tutorial (or can you show me some code) that shows how to sort my result set, in addition to using the pagination?

    I would like to have a couple drop down lists to filter query results across each page. Such as by date, alphabetically, etc. …where you can select the filter on any page and the selection carries across all pages until a new selection is made.

    I have scoured the web and cannot find php code that combines paging and sorting. (I’m assuming it’s probably because it’s difficult to do.)

    I have been struggling with this for over two weeks. I’ve tried using both straight php code, and a mix of php and ajax to no avail. I’m a total noob to php… using it because the web host does not support ASP or ASP.NET which I’m a bit more familiar with.

    My brain hurts and I’m running out of steam… I could really use some help form an expert.

    Thanks in advance,

    Jeff

  6. Joy says:

    every thing works fine except this four lines
    Notice: Undefined index: ipp in D:\wamp\www\yourbettingguide.net_new\includes\paginator.class.php on line 25

    Notice: Undefined index: page in D:\wamp\www\yourbettingguide.net_new\includes\paginator.class.php on line 35

    Notice: Undefined index: ipp in D:\wamp\www\yourbettingguide.net_new\includes\paginator.class.php on line 100

    Notice: Undefined index: ipp in D:\wamp\www\yourbettingguide.net_new\includes\paginator.class.php on line 101

    and this is my code
    items_total = $num_rows[0];
    $pages->mid_range = 5;
    $pages->paginate();
    echo $pages->display_pages();

    $query = “SELECT match_date, home_team, away_team, home_score, away_score
    FROM league2
    ORDER BY match_date DESC $pages->limit”;

    $result = mysql_query($query);

    echo “”;
    while($row2 = mysql_fetch_array( $result )) {

    echo “”;
    echo $row2['match_date'];
    echo “”;
    echo $row2['home_team'];
    echo “”;
    echo $row2['home_score'];
    echo “”;
    echo $row2['away_score'];
    echo “”;
    echo $row2['away_team'];
    echo “”;
    }
    echo “”;
    ?>

    how can i fix this? if anybody knows please help me…….

    • Joy says:

      this is my code
      items_total = $num_rows[0];
      $pages->mid_range = 5;
      $pages->paginate();
      echo $pages->display_pages();

      $query = “SELECT match_date, home_team, away_team, home_score, away_score, prediction
      FROM premier_league2
      ORDER BY match_date DESC $pages->limit”;

      $result = mysql_query($query);

      echo “”;
      while($row2 = mysql_fetch_array( $result )) {

      echo “”;
      echo $row2['match_date'];
      echo “”;
      echo $row2['home_team'];
      echo “”;
      echo $row2['home_score'];
      echo “”;
      echo $row2['away_score'];
      echo “”;
      echo $row2['away_team'];
      echo “”;
      }
      echo “”;

      ?>

  7. Joy says:

    my code is auto editing when i posting here, you can view entire code here http://www.phpriot.com/3386 need help…….

  8. DC says:

    Hi, I had the same -5-5 type error and fixed the problem by writing one line to check before we run a darn thing in our func.

    function paginate(){

    in func paginate add the line below

    //DC Mod Prevent ERRORs If No Items Found …
    if ($this->items_total != 0){

    This is where all the pagination code resides
    then at the end just before the func close statment
    add

    }

    I did this for 2 of the class funcs that caused ers and this will fix the err prob.
    I think this type of fix or somthing like it should be built into the class allready.
    Otherwise fantastic class wouldn’t think of using anything else.

    DC

  9. For those of us that need to be able to set the page links href attribute (if you are using mod_rewrite for example), i’ve tweaked this (most excellent) script to add an option “link_href”.
    You can find the code on PasteBin: http://phpbin.net/x/414326483

    for instance, in a wordpress theme, you could set $pages->link_href= the_permalink();

  10. Scottie says:

    I am having issues with putting this in my existing page……getting:

    You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ”Eiger” at line 1

    Code is here: http://data.oddunity.com/trouble.txt
    Example run here: http://data.oddunity.com/allresults_new.php

    I did replace the config data with an include as well as the stylesheet

    • admin says:

      Your select query is wrong. You have SELECT COUNT(*) FROM spos = '$_REQUEST[tb1]' and replacing $_REQUEST[tb1] with something like ‘Teal Island’, it becomes SELECT COUNT(*) FROM spos = 'Teal Island'In other words, your query is either missing the table to query or the field. The query should be something like SELECT COUNT(*) FROM table WHERE spos = '$_REQUEST[tb1]' or SELECT COUNT(*) FROM spos WHERE fieldname= '$_REQUEST[tb1]'

  11. Hi, this is working just great for me, but I have one question. How can I assign or get the echo $pages->display_pages(); to goto my template file ?

  12. Sorry, I meant my smarty .tpl file

  13. sukrudal says:

    Hi,
    I have question, when i use this
    echo $pages->display_jump_menu().$pages->display_items_per_page();
    commend, display next line in my page with firefox (no problem on ie6)

    How can i solve this problem, please help.
    Thanks

  14. Noel Velez says:

    Hi,
    Is it possible to override the default value of $default_ipp? Do I need to extend the class if two scripts should have two different default values for the number of items to display per page?
    Thank you.

  15. Matt says:

    What’s your real name and email address so I can give you full credit for the class in my javadoc blocks.
    /**
    * @author SOMEBODY
    */

  16. Arif Majid says:

    Excellent work DONE !!!

    But There is a PROBLEM …

    “Select * from table $pages->limit”;
    if you have no records in the table u get a definite warning

    FIX :if($num_rows == 0){
    $limit = “”;
    }else{
    $limit = $pages->limit;
    }

    Change the second query to this
    “Select * from table $limit”;

    There you go…. You Have 100% perfect paginator class .. thnx a lot !! ;)

  17. Newport says:

    This is an old post so you probably haven’t seen comments on it in a while, but nice work! I was about to write a pagination class for a project I’m working on and thankfully I Googled first and found yours. I integrated it into a WordPress project with one simple tweak: At line 40, just before if ($_GET) I added the following: $root_path = parse_url($_SERVER['REQUEST_URI'],PHP_URL_PATH);

    Then use $root_path in the various links in the class in place of $_SERVER[PHP_SELF] etc. Works like a charm and saved me tons of time. Thanks!

  18. Maria says:

    Hello,
    I’m so greatfull !! Pagination was always my weak point. Now works like a charm. The only that I’m unable to setup (other than hardcoding in class file) is the records per page. Till now I’m chanaging var $default_ipp = 10;

    Maria

  19. Cat says:

    You are my hero!!!!
    Thank you!
    Thank you!
    Thank you!

  20. Mehrdad says:

    Really Great!
    Thanks!

  21. Igor Ianukov says:

    I am not getting it to work. Anybody knows why it aint working ? I only get the links to the pages in a correct number but first it does not limit me the display, it brings out all of the rows and second, if you click on any page link it just reloads the whole page and shows again all of the rows. So the limit aint working and the page links dont make any difference.


    items_total = $num_rows[0];
    $pages->mid_range = 7; // Number of pages to display. Must be odd and > 3
    $pages->paginate();

    $sql ="SELECT id, thumb, offer_description
    FROM $tablename
    WHERE continent = '".$continente."'
    AND nature = '".$nature."'
    ORDER BY id ASC $pages->LIMIT
    ";

    $result = @mysql_query ($sql);

    while ($row = mysql_fetch_array($result, MYSQL_ASSOC)) {

    echo '';

    echo'';

    echo '';

    echo'';

    echo '' .($row['offer_description']). ''."";

    echo '';

    echo '';
    }

    echo $pages->display_pages();
    // echo "Page: $pages->current_page of $pages->num_pages\n";

    And here, it justs writes it in full on the page except for the variables which parses fine but instead of making the SELECT query work, it writes me on the page black on white SELECT from etc, so it is echoing the commands as strings of characters it does not recognize it is a SQL query.

    echo "SELECT id FROM table $pages->limit (retrieve records $pages->low-$pages->high from table - $pages->items_total item total / $pages->items_per_page items per page)";

    ?>

  22. Igor Ianukov says:

    I copy and paste again all of the code as plain text. It was rejected by the server here. Like I said, it does not LIMIT the number of displayed rows, it shows all and the page links dont fetch anything, they just reload the page

    require_once(‘paginator.class.php’);
    require_once (‘mysqli_connect.php’);

    $tablename = “featured_offers”;
    $continente = $_GET['y'];
    $nature = $_GET['x'];

    $query = “SELECT COUNT(*) FROM $tablename WHERE continent = ‘”.$continente.”‘ AND nature = ‘”.$nature.”‘ “;
    $result = mysql_query($query) or die(mysql_error());
    $num_rows = mysql_fetch_row($result);

    $pages = new Paginator;
    $pages->items_total = $num_rows[0];
    $pages->mid_range = 7; // Number of pages to display. Must be odd and > 3
    $pages->paginate();

    $sql =”SELECT id, thumb, offer_description
    FROM $tablename
    WHERE continent = ‘”.$continente.”‘
    AND nature = ‘”.$nature.”‘
    ORDER BY id ASC $pages->LIMIT
    “;

    $result = @mysql_query ($sql);
    // $num_rows[0] = mysql_num_rows($result);

    while ($row = mysql_fetch_array($result, MYSQL_ASSOC)) {

    echo ”;

    echo”;

    echo ‘‘;

    echo”;

    echo ” .($row['offer_description']). ”.”";

    echo ”;

    echo ”;

    }

    echo $pages->display_pages();
    // echo “Page: $pages->current_page of $pages->num_pages\n”;
    echo “SELECT id FROM table $pages->limit (retrieve records $pages->low-$pages->high from table – $pages->items_total item total / $pages->items_per_page items per page)”;

  23. Dorogz says:

    WIERD!

    Can anyone help here? If my query finds only one field for data, the data is NOT displayed! Moreover, displayed data is always one field less! I can’t figure out what I’m doing wrong!!

    Thanks for your HELP!!!

    limit";
    $result = mysql_query($sql) or die(mysql_error($sql));
    $converter = new Encryption;
    ?>
    display_items_per_page();?> display_pages();?>

    <?php
    if(mysql_fetch_row($result)

    Query does not match any data

    <a class="more" href="./details.php?u=encode($row['id']);?>">»

  24. Dorogz says:

    WIERD!

    Can anyone help here? If my query finds only one field for data, the data is NOT displayed! Moreover, displayed data is always one field less! I can’t figure out what I’m doing wrong!!

    Thanks for your HELP!!!

    limit”;
    $result = mysql_query($sql) or die(mysql_error($sql));
    $converter = new Encryption;
    ?>
    display_items_per_page();?> display_pages();?>

    <?php
    if(mysql_fetch_row($result)

    Query does not match any data

    <a class="more" href="./details.php?u=encode($row['id']);?>”>»

  25. Feyyazesat says:

    hello, this is aweosome very good processing on any page :) just I have a little problem,as an interesting thing my querystring put the &do= variable spontaneously and result of this if I click to 1. 2. or All link in display_pages’s result, then I was see blahblah&do=&do=&do=… I didn’t find based on where, but I applied one simple solution,

    when the display_pages function return $this->return, I change that with return str_replace (“&do=”, “”, $this->return);

    if also you encounter like that problem this may help you… good works.

Trackbacks/Pingbacks

Leave a Reply

You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>