Pagination Class - Script to paginate content

The PHP Pagination Class presented in this page can be used to paginate contents stored in a MySQL database, or into an Array, or eaven a string with large text content that you want to divide into multiple pieces, with a page for each piece.
The script is very flexible, you can easily set the number of rows displayed on the page, or in the case you paginate a large text, you can choose to divide the text into a specific number of pieces or according to a number of maximum characters (without breaking words).
Details about the code are in the class comments.


You can copy the class code presented below or click -> Pagination Class to download a ZIP archive that contains the class and examples to use it.

Pagination Class code

<?php
/* Pagination Class - http://coursesweb.net/php-mysql/ */
class Pagination {
  /* EDIT data in this array if you want to paginate content stored in a MySQL table
   Add your data for connecting to MySQL database (MySQL server, user, password, database name) */
  protected $mysql = array(
   'host'=> 'localhost',
   'user'=> 'root',
   'pass'=> 'password',
   'dbname'=> 'database_name'
  );
  public $table = 'pgtest';           // HERE add the mysql table name

  // properties
  public $rowsperpage = 10;    // number of articles displayed in the page
  public $txtchr = 800;        // maximum numbers of characters for article (if paginate text-content)
  public $txtpieces = 0;       // number of pieces to divide text (if paginate text-content)
  public $range = 3;           // range number of links around the current
  protected $conn = false;     // will store the mysql connection
  protected $idpage = 0;       // the index of the current page
  protected $totalpages = 0;   // number of total pages
  protected $pag;              // to store the name of the file ($_SERVER['PHP_SELF'])

  
  // Constructor
  public function __construct() {
    // sets the properties: $pag, and $idpage (integer, positive)
    $this->pag = $_SERVER['PHP_SELF'];
    if(isset($_GET['pg'])) $this->idpage = intval(abs($_GET['pg']));
  }

  // method to set the mysql connection
  public function setConn() {
    // if it connects successfully to MySQL database, store the connection in the $conn property
    if($conn = new mysqli($this->mysql['host'], $this->mysql['user'], $this->mysql['pass'], $this->mysql['dbname'])) {
      $sql = "SET NAMES 'utf8'";
      if($conn->query($sql)) $this->conn = $conn;
    }
    return $this->conn;
  }

  // Select the rows for the current page from the mysql table, or from a received Array. Returns an Array with the rows
  public function getMysqlRows() {
    $this->setConn();          // calls the setConn() method to set the MySQL connection
    $startrow = $this->idpage * $this->rowsperpage;           // the row from which start to select the content
    $re_cnt = '';              // the variable that will be returned

    // if there is a connection to MySQL
    if($this->conn !== false) {
      // SELECT to set the total number of pages ($totalpages)
      $sql = "SELECT COUNT(*) FROM `$this->table`";

      // perform the query, then Selects the rows
      if($resql = $this->conn->query($sql)) {
        // if the $resql contains at least one row, takes and sets $totalpages
        if($resql->num_rows > 0) {
          $row = $resql->fetch_row();
          $this->totalpages = ceil($row[0] / $this->rowsperpage);

          // Define the SELECT to get the rows for the current page
          $sql = "SELECT * FROM `$this->table` LIMIT $startrow, $this->rowsperpage";
          if($resql = $this->conn->query($sql)) {
            // if the $resql contains at least one row
            if($resql->num_rows > 0) {
              // EDIT THE NAME OF COLUMNS AND FORMAT THE DATA WITH HTML TAGS AS YOU WHISH
              while($row = $resql->fetch_assoc()) {
                $re_cnt .=  '<h3>'. $row['title']. '</h3>'. $row['id']. '<div class="content">'. $row['content']. '</div>';
              }
            }
            else $re_cnt .= '0 results';
          }
          else $re_cnt .= '0 results in the table';
        }
      }
      else $re_cnt .= 'Error: '. $this->conn->error;

      $this->conn->close();
    }
    else $re_cnt .= 'No connection to MySQL table'. mysqli_connect_error();

    return $re_cnt;
  }

  // receives an Arry with the content for all pages. Returns the content for the current page
  public function getArrRows($arr) {
    $startrow = $this->idpage * $this->rowsperpage;           // the element from which start to select
    $ar_page = array_slice($arr, $startrow, $this->rowsperpage);        // gets the elements for current page
    $nre = count($ar_page);
    $this->totalpages = ceil(count($arr) / $this->rowsperpage);        // sets the total number of pages
    $re_cnt = '';              // the variable that will be returned

    // HERE ADDS HTML TAGS TO FORMAT THE ZONE THAT CONTAINS EACH ELEMENT
    for($i=0; $i<$nre; $i++) {
      $re_cnt .= '<div class="content">'. $ar_page[$i]. '</div>';
    }

    return $re_cnt;
  }

  // method to split the text into number of characters (specified in the $txtchr property) without breaking words
  public function getText($text) {
    // if the $txtpieces higher than 0, divide the $text into a number of pieces specified in $txtpieces
    // otherwise, split the text according to the number of characters specified in $txtchr property
    if($this->txtpieces>0) {
      $this->txtchr = ceil(strlen($text) / $this->txtpieces);    // set $txtchr (length of text piece) according to number of pieces
    }

    // split the text and create an Array with string pieces. Returns the content for the current page
    $newtext = wordwrap($text, $this->txtchr, '#|#');
    $ar_text = explode('#|#', $newtext);
    $nr_pieces = count($ar_text);

    // if paginate by number of pieces, and too many pieces - merge the last two pieces
    if($this->txtpieces>0 && $nr_pieces>$this->txtpieces) {
      $ar_text[$nr_pieces-2] .= ' '. $ar_text[$nr_pieces-1];
      unset($ar_text[$nr_pieces-1]);
    }
    
    $this->totalpages = count($ar_text);       // sets the number of total pages
    if($this->idpage > $this->totalpages) $this->idpage = $this->totalpages;

    // sets a string to be added at the end of the text content, if not the last page.
    $end = ($this->idpage+1)<$this->totalpages ? ' ...[<i> Continue to next page</i>].' : '';

    return $ar_text[$this->idpage]. $end;
  }

  // method that sets the links
  public function getLinks() {
  $re_links = '';         // the variable that will contein the links and will be returned
  $pag_get = '?pg=';      // the name for the GET value added in URL

  // if $totalpages>0 and totalpages higher then $this->idpage
  if($this->totalpages > 0 && $this->totalpages > $this->idpage) {
    // links to first and back page, if it isn't the first page
    if ($this->idpage > 0) {
      // show << for link to 1st page
      if(($this->idpage + 1) > $this->range) $re_links .= '<a href="'. $this->pag. '" title="1">(1) &lt;&lt;</a>';  

      // show < for link to back page
      if(($this->idpage - $this->range) > 2) $re_links .= ' <a href="'. $this->pag. $pag_get. ($this->idpage - $this->range - 1) .'" title="'. ($this->idpage - $this->range) .'">('. ($this->idpage - $this->range) .')&lt;</a>';
    }

    // sets the links in the range of the current page
    for($x = ($this->idpage - $this->range + 1); $x <= ($this->idpage + $this->range); $x++) {
      $ipg = max(0, ($x - 1));       // index of page in URL
      // if it's a number between 0 and last page
      if (($x > 0) && ($x <= $this->totalpages)) {
        // if it's the number of current page, show the number without link, otherwise add link
        if ($x == ($this->idpage + 1)) $re_links .= ' [<span style="font-weight:800;">'. $x .'</span>] ';
        else $re_links .= ' <a href="'. $this->pag. $pag_get. $ipg. '" title="'. $x. '">'. $x .'</a>';  
      }
    }

    // If the current page is not final, adds link to next and last page
    if ($this->idpage < $this->totalpages) {
      // show > for next page
      if(($this->idpage + $this->range) < ($this->totalpages - 3)) $re_links .= ' <a href="'. $this->pag. $pag_get. ($this->idpage + $this->range + 1) .'" title="'. ($this->idpage + $this->range +2) .'">&gt;('. ($this->idpage + $this->range +2) .')</a>';
      //  show >> for last page
      if($this->totalpages > $this->range && $this->totalpages > ($this->idpage + 2)) $re_links .= ' <a href="'. $this->pag. $pag_get. ($this->totalpages - 1) .'" title="'. $this->totalpages .'">&gt;&gt; ('. $this->totalpages. ')</a> ';
    }
  }

    // adds all links into a DIV and return it
    if(strlen($re_links)>1) $re_links = $re_links;
    return $re_links;
  }
}
?>

How to use this Pagination script

- If you want to paginate rows stored into a MySQL table:
1. Copy the class code into a PHP file (for example named: "class.pagination.php") on your server.
2. Include the class into your PHP script, with:
include('class.pagination.php');
3. Create an object instance of the class, with this syntax:
$objPg = new Pagination();
4. In the place you want to display the paginated content, calls the class method according to the source to paginate (after you have created the class instance): 5. In the place you want to display the pagination links, calls the getLinks() method:
echo $objPg->getLinks();

Pagination Class properties

- To set the number of rows (array elements) that will be displayed in a page, modify the value of the $rowsperpage property (initiialy set to 10).
- The property: $txtchr defines the maximum number of characters for the text content to be paginate.
- The property: $txtpieces defines the number of pieces in which the text will be divided. In this case, if the value is higher than 0, the number of characters ($txtchr) will not be taken into consideration.
- The property: $range sets the range number of links around the current link.

These properties can be set in the class code, or dinamicaly in the script, after you have created the instance of the class (as you can see in the examples below).

• The archive "pagination_class_script.zip" which you can download from the link above, contains examples with each type of pagination and detailed explanations.

Code example to use the Pagination class

1. Paginate contents from MySQL database:
<?php
// include the Pagination class
include('class.pagination.php');

// create object instance of the class
$objPg = new Pagination();

// if you want to change the name of the table, set the "table" property
// $objPg->table = 'other_table';

// if you want to change the number of rows added in page, set the "rowsperpage" property
// $objPg->rowsperpage = 8;

// output /display the conntent
echo $objPg->getMysqlRows();

// output / display pagination links
echo $objPg->getLinks();
?>

2. Paginate contents stored into an array:
<?php
// Array with data
$source = array('a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','y','x','z');

// include the Pagination class
include('class.pagination.php');

// create object instance of the class
$objPg = new Pagination();

// change the number of elements displayed on the page
$objPg->rowsperpage = 8;

// output /display the conntent
echo $objPg->getArrRows($source);

// output / display pagination links
echo $objPg->getLinks();
?>

3. Pagination text string:
<?php
// A string with the text content to paginate
$source = 'Here add a large text string, or you can get the string from an external file, for example with the file_get_contents() function.';

// include the Pagination class
include('class.pagination.php');

// create object instance of the class
$objPg = new Pagination();

// change the number of characters for the piece of text content
$objPg->txtchr = 40;

// if you want to paginate the text content by a number of pieces, set the "txtpieces" property
// $objPg->txtpieces = 6;

// output /display the conntent
echo $objPg->getText($source);

// output / display pagination links
echo $objPg->getLinks();
?>

This script is free (does not provide support or personal modifications).

It was successfully tested for a general configuration on localhost with XAMPP. If on other systems does not work properly, depends on their configuration.