分页是实际开发中再常见不过的一个应用场景。主要难点在于拼凑分页页码,注意说的不是保持参数之类的,而是控制页码中一共显示多少页,到哪一页应该显示个…表示还有更多。下面是我自己写的一个分页类,可自定义的参数有:
mainClass,整个分页页码是一个ul,这是ul的class。默认pagination
itemClass,每一个普通页码(1,2,3之类)链接是一个li,这是li的class。默认无
prevText,上一页上边显示的文字,默认“上一页”,比如你可以设置为”<
prevClass,上一页的class,默认无,比如你可能设置为prev
nextText,下一页上边显示的文字,默认“下一页”,比如你可以设置为”>>”
nextClass,下一页的class,默认无,比如你可以设置为next
activeClass,当前页的class,默认为active
disabledClass,不可点页码的class,默认为disabled
url,基本URL,默认为空,也就是参数直接挂在当前链接路径之后,一般框架都对路由美化,最好设置一下
p,页码参数名,默认page
showPageCount,页码最多显示多少页,也就是即使有100页也只显示多少,不可能全部显示,否则太长,默认10
prepend,在页码最左边插入一项,注意这得是个li,因为它是ul的子元素。一般分页码最左会加个“返回列表”。默认空
append,在页码最右边插入一项,同上。默认空
addDot,省略的页码最前一个添加…,默认TRUE
看着蛮多,基本够用了。至于那些一共XX条,每页显示XX条,当前第XX页,这些本来就知道了的,实例化这个分页类需要的参数就是这三个值,没必要放到分页代码里边,本来就知道需要显示直接写上就得了。实例化时需要传递以下参数
page,当前页,也就是当前是第几页,必须
total,总页数,必须
params,跳转连接上携带的参数,可选,不传时将选择$_GET的参数全部加上
使用方法,引入Paginagion类,提供参数new即可。得到的对象可以设置以上自定义参数,直接给属性赋值即可,最后show()方法返回分页的HTML代码。如默认参数得到的结果如下:
$page = empty($_GET['page']) ? 1 : $_GET['page'];
$total = empty($_GET['total']) ? 20 : $_GET['total'];
$obj = new Pagination($page, $total);
$pagination = $obj->show();
一共20页,最多显示10页。
也可以设置一些参数,如下:
$page = empty($_GET['page']) ? 1 : $_GET['page'];
$total = empty($_GET['total']) ? 20 : $_GET['total'];
$obj = new Pagination($page, $total, array('cid' => 2, 'kw' => 'Windows 10'));
$obj->prevText = '<
$obj->nextText = '>>';
$obj->append = '
新建XX';$obj->prepend = '
返回列表';$obj->prevClass = 'prev';
$obj->nextClass = 'next';
$obj->showPageCount = 9;
$pagination = $obj->show();
注:css样式使用的是Bootstrap,生成的页码结果也是按照Bootstrap中的分页来的。
代码如下:
class Pagination
{
public $mainClass = 'pagination';//ul的class
public $itemClass = '';//li的class
public $prevText = '上一页';//上一页的文字
public $prevClass = '';//上一页的class
public $nextText = '下一页';//下一页的文字
public $nextClass = '';//下一页的class
public $activeClass = 'active';//当前页面class
public $disabledClass = 'disabled';//不能点页面class
public $url = '';//页面 基本的url
public $p = 'page';//分页参数名
public $showPageCount = 10;//最多显示10页,超过显示...
public $prepend = '';//最左边插入的内容,是一个li
public $append = '';//最右边插入的内容,是一个li
public $addDot = TRUE;//是否添加...
private $page;//当前页
private $total;//总页数
private $params = array();//传递的参数
public function __construct($page, $total, array $params = array())
{
$this->page = $page;
$this->total = $total;
$this->params = empty($params) ? $_GET : $params;
}
/**
* 获得基本的URL,包含要传递的参数,去掉分页参数
*/
private function getBaseURL()
{
$URL = $this->url;
$params = $this->params;
unset($params[$this->p]);
$queryString = http_build_query($params);
if (empty($queryString))
{
return $URL.'?'.$this->p.'=';
}
else
{
return $URL.'?'.$queryString.'&'.$this->p.'=';
}
}
public function show()
{
$HTML = '
- ';
$hasPend = FALSE;
if (!empty($this->prepend))
{
$hasPend = TRUE;
$HTML .= $this->prepend;
}
if ($this->total <= 1)
{
if (!empty($this->append))
{
$hasPend = TRUE;
$HTML .= $this->append;
}
if ($hasPend)
{
return $HTML.'
';}
else
{
return '';
}
}
$startDot = $endDot = '';
$max = $this->showPageCount;
$total = $this->total;
$d = floor(($max - 2)/2);//中位数
$page = $this->page;//当前页
$dot = $this->addDot ? '...' : '';
$url = $this->getBaseUrl();
$isOdd = $max%2 == 1 ? TRUE : FALSE;//是否奇数,偶数数两端有...时得减小某端的一个页码,这里取左边
//拼凑上一页与第一页。上一页、第一页、最末页、下一页是固定的。没有...之类
if ($page == 1)
{
$HTML .= '
'.$this->prevText.'';$HTML .= '
1';}
else
{
$HTML .= '
'.$this->prevText.'';$HTML .= '
1';}
//准备循环起始点
if ($total <= $max)
{
$start = 2;
$end = $total - 1;
}
else
{
if ($page - $d <= 2)
{
$start = 2;
$end = $max - 1;
$endDot = $dot;
}
else
{
if ($page + $d >= $total - 1)
{
$start = $total - $max + 2;
$end = $total - 1;
$startDot = $dot;
}
else
{
$start = $isOdd ? ($page - $d) : ($page - $d + 1);
$end = $page + $d;
$startDot = $dot;
$endDot = $dot;
}
}
}
for ($i = $start; $i <= $end; $i++)
{
$active = '';
if ($i == $page)
{
$active = $this->activeClass;
}
$showText = $i;
if ($i == $start)
{
$showText = $startDot.$showText;
}
if ($i == $end)
{
$showText = $showText.$endDot;
}
$HTML .= '
'.$showText.'';}
//拼凑最末页和下一页
if ($page == $total)
{
$HTML .= '
'.$total.'';$HTML .= '
'.$this->nextText.'';}
else
{
$HTML .= '
'.$total.'';$HTML .= '
'.$this->nextText.'';}
if (!empty($this->append))
{
$HTML .= $this->append;
}
$HTML .= '';
return $HTML;
}
}