You can use my pagination class if you like. It requires that you know how many records exist, and requires that you can control how many records show up per page:
PHP Code:
<?php
class Pagination {
public $menu;
function __construct($count, $opt = array()) {
$this->saveList($count, $opt);
}
public function returnList($total_number_records, $options = array()) {
$defaults = array(
'prefix' => '',//string which precedes page number in list
'activeClass' => 'active',//if we're on this page, anchor carries this class
'key' => 'p',//?key=value
'assignKey' => '{key}={value}',
'limit' => 10,//how many records per page
'listcount' => 10,//how many pages to show in list
'wrap' => 'li',//html entity wrapper for each page number
'seperator' => " ",//seperation deliminator
'page' => $_SERVER['PHP_SELF'],//page targeted by pagination
'parseGet' => true,
'nextLink' => 'Next >',//next link text or HTML
'prevLink' => '< Prev'//same as above
);
$opt = array_merge($defaults, $options);
$pattern = str_replace('{key}', '%1$s', $opt['assignKey']);
$pattern = str_replace('{value}', '%2$d', $pattern);
$q_sym = '';
if($opt['parseGet']) {
$request_page = explode("?", $opt["page"]);
$q_sym = "?";
if(sizeof($request_page > 1)) {
$sym = "?";
$opt["page"] = $request_page[0];
foreach($_GET as $k => $v) {
if ($k == $opt["key"]) continue;
$opt["page"] .= $sym.$k."=".$v;
$sym = "&";
$q_sym = "&";
}
}
}
//first, some math (where are we?)
$id = (!empty($_GET[$opt["key"]])) ? $_GET[$opt["key"]]: 1;
$here = $id * $opt["limit"];
$bridgeleft = $here - ($opt["limit"] * (floor($opt["listcount"] / 2)));
$bridgeleft = ($bridgeleft < 0) ? 0 : $bridgeleft;
$bridgeright = $bridgeleft + ($opt["limit"] * (ceil($opt["listcount"])));
$oldbridgeright = $bridgeright;
$bridgeright = ($bridgeright > $total_number_records) ? $total_number_records : $bridgeright;
$bridgeright = ceil($bridgeright / $opt["limit"]) * $opt["limit"];// round up to nearest $opt["limit"]
$diff = $oldbridgeright - $bridgeright;
//
if($diff < $opt["limit"] * $opt["listcount"]) {
$bridgeleft -= $diff;
$bridgeleft = ($bridgeleft < 0) ? 0 : $bridgeleft;
}
$last = ceil($total_number_records / $opt["limit"]);
$idinc = $id + 1;
$iddeinc = $id - 1;
$seperate_beginning = '';
if($bridgeleft > 1 && $bridgeleft < 10) {
$seperate_beginning = ' ... ';
}
elseif($bridgeleft >= 10) {
$div_num = floor($bridgeleft / 2);
//$opt["key"].'='.$div_num
$seperate_beginning = ' .. '."<".$opt["wrap"].'> <a href="'.$opt["page"].$q_sym.sprintf($pattern, $opt['key'], $div_num).'">'.$div_num.'</a> </'.$opt["wrap"].">".' .. ';
}
$nextoption = ($id != $last) ? "<".$opt["wrap"].'> <a href="'.$opt["page"].$q_sym.sprintf($pattern, $opt['key'], $idinc).'">'.$opt["nextLink"].'</a> </'.$opt["wrap"].">" : "";
$prevoption = ($id != 1) ? "<".$opt["wrap"].'> <a href="'.$opt["page"].$q_sym.sprintf($pattern, $opt['key'], $iddeinc).'">'.$opt["prevLink"].'</a> </'.$opt["wrap"].">" : "";
$optional_first = ($id != 1) ? "<".$opt["wrap"].'> <a href="'.$opt["page"].$q_sym.sprintf($pattern, $opt['key'], 1).'">First</a>'.$seperate_beginning.'</'.$opt["wrap"].">" : '';
$list = $prevoption.$nextoption.$optional_first;
$inc = $bridgeleft / $opt["limit"];
$seperate = "";
for($i = $bridgeleft; $i < $bridgeright; $i += $opt["limit"]) {
$optional = ($id == ++$inc) ? 'class="'.$opt["activeClass"].'" ' : "";
$list .= "<".$opt["wrap"].'>'.$seperate.'<a '.$optional.'href="'.$opt["page"].$q_sym.sprintf($pattern, $opt['key'], $inc).'">'.$opt["prefix"].$inc.'</a></'.$opt["wrap"].">";
$seperate = $opt["seperator"];
}
$seperate_end = '';
if($last - $inc < 10 && $last - $inc > 1) {
$seperate_end = ' ... ';
}
elseif($last - $inc >= 10) {
$div_num = ceil(($last - $inc) / 2);
$seperate_end = ' .. '."<".$opt["wrap"].'> <a href="'.$opt["page"].$q_sym.$opt["key"].'='.$div_num.'">'.$div_num.'</a> </'.$opt["wrap"].">".' .. ';
}
if($id != $last) {
$list .= "<".$opt["wrap"].'>'.$seperate_end.'<a href="'.$opt["page"].$q_sym.sprintf($pattern, $opt['key'], $last).'">Last</a> </'.$opt["wrap"].">";
}
return $list;
}
public function saveList($count, $opt = array()) {
$this->menu = $this->returnList($count, $opt);
}
}
?>
To use this class you're going to probably have to do something like this:
PHP Code:
//calculate how many records
$count = 100;//just an example
$per_page = 20;//20 records per page
$paginate = new Pagination($count, array(
'limit' => $per_page,
'key' => 'page'//this will be the $_GET var that we calculate with
))
You'll need to take the $_GET['page'], along with the $per_page to calculate $start and $length instead of what you're doing currently.
Don't have time for a more detailed explanation, though I'm sure you can get some good help here from those who can read PHP well. All of the options for my class can be read from the $defaults array().
Once you've intialized the Paginate class, it can be displayed anywhere on the page like this:
PHP Code:
<ul>
<?php echo $paginate->menu;?>
</ul>
By default, it is an unordered list, which means it will have to be styled to be inline. You can choose a different HTML entity to wrap each item with the 'wrap' option if you wish.