<?php
/**
* 通用分頁類
* Author:Zero QQ:93133
* ver 1.2.20120519 修正版
*/
class pagination{
private $pstyle=array();
private static $url=array();
public $arg=array();
public $cfg=array(
'text'=>array('首頁','上一頁','下一頁','尾頁'),
'pagesize'=>20,
//htmltpl=> "list{\$page}.shtml",
'listtpl'=>'[{$page}]',//仿搜索引擎頁模板
'tpl'=>array('t','條','l','s'), //默認調用方式
// total=>0 記錄總數
//'attachtotal'=>false
);
public $totalpage; //總頁數
function __construct(array $cfg){
is_numeric($cfg['total'])&&$cfg['total']>=0 or exit('必須傳入有效記錄數');
if(!is_numeric($cfg['pagesize'])||$cfg['pagesize']<=0) unset($cfg['pagesize']);
$this->cfg=array_merge($this->cfg,$cfg);
//計算分頁總數
$this->totalpage=ceil($this->cfg['total']/$this->cfg['pagesize']);
if($this->cfg['page']){ //傳入當前頁 適合html,ajax 需同時傳入cfg[htmltpl]才起作用
$this->arg['page']=$this->cfg['page'];
}
else{
//分析URL中的當前頁
//2011-5-29修改分析方法,以兼容URL重寫後的地址
self::$url or self::$url=parse_url($_SERVER['REQUEST_URI']);
parse_str($this->cfg['arg']?$this->cfg['arg']:self::$url['query'],$this->arg);
$this->arg['page']=is_numeric($this->arg['page'])&&$this->arg['page']<=$this->totalpage?abs(ceil($this->arg['page'])):1;
}
//客戶端緩存記錄總數
($this->cfg['total']>8000||$this->totalpage>400)&&!isset($this->cfg['attachtotal']) and $this->cfg['attachtotal']=true;
$this->cfg['attachtotal']&&!self::totalcache() and self::totalcache($this->cfg['total']);
}
public static function totalcache($total=null,$cachetime=3600){
self::$url or self::$url=parse_url($_SERVER['REQUEST_URI']);
$urlparts=self::$url;
parse_str($urlparts['query'],$urlparts['query']);
unset($urlparts['query']['page'],$urlparts['query']['ajax']);
//header('sdfsdf:'.serialize($urlparts));
$key='_total_'.md5(serialize($urlparts));
if($total!=null){ //設置緩存
setcookie($key,$total,$_SERVER['REQUEST_TIME']+$cachetime);
}
else{ //獲取緩存
return $_COOKIE[$key];
}
}
/**
* 創建翻頁鏈接
*
* @param int $page 頁數
* @return string 鏈接字符串
*
*/
private function buildurl($page){
if(!is_numeric($page)){ //javascript select控件翻頁
$arg=$this->arg;
$arg['page']='{page}';
$url= '\'?'.http_build_query($arg)."'.replace(escape('{page}'),$page)";
}
elseif(is_numeric($this->arg['page'])&&$this->cfg['htmltpl']){ //靜態翻頁
$url=str_replace('{$page}',$page==1?null:$page,$this->cfg['htmltpl']);
}
else{ //PHP翻頁
$arg=$this->arg;
$arg['page']=$page;
if($this->cfg['ajax']){
if(isset($_SERVER['HTTP_X_REQUESTED_WITH'])){ //ajax翻頁
$οnclick="\" οnclick=\"{$this->cfg['ajax']}.call(this,$page);return false";
$path=self::$url['path'];
}
else{
unset($arg['ajax']);
}
}
$query= '?'.http_build_query($arg);
$url=$path.$query.$onclick;
}
return $url;
}
/**
* 文本輸入框樣式
*
*/
private function i(){
$this->pstyle[]='跳轉<input type="text" title="輸入頁數,按回車跳轉" style="width:30px;text-align:center" οnkeydοwn="javascript:if(event.keyCode==13){'.($this->cfg['ajax']?$this->buildurl('this.value'):"location.href={$this->buildurl('this.value')};return false;}").'" />頁';
}
/**
* 下拉列表
*
*/
private function s(){
if($this->totalpage>300) return $this->i(); //大於300頁,用輸入方式代替
$str='<select size="1" οnchange="'.($this->cfg['ajax']?$this->buildurl('this.value'):"location.href={$this->buildurl('this.value')}").'">';
for($i=1;$i<=$this->totalpage;$i++){
$str.="<option value='$i'".($this->arg['page']==$i?' selected':null).">第{$i}頁</option>";
}
$str.="</select>";
$this->pstyle[]=$str;
}
/**
* 首頁樣式
*
*/
private function f($show=true){
$this->pstyle[]=$this->arg['page']==1&&$show? $this->cfg['text'][0]:"<a href=\"{$this->buildurl(1)}\">{$this->cfg['text'][0]}</a>";
}
/**
* 尾頁樣式
*
*/
private function e($show=true){
$this->pstyle[]=$this->arg['page']==$this->totalpage&&$show? $this->cfg['text'][3]:"<a href=\"{$this->buildurl($this->totalpage)}\">{$this->cfg['text'][3]}</a>";
}
/**
* 上一頁樣式
*
*/
private function p($show=true){
$this->pstyle[]=$this->arg['page']<2&&$show? $this->cfg['text'][1]:"<a href=\"{$this->buildurl($this->arg['page']-1)}\">{$this->cfg[text][1]}</a>";
}
/**
* 下一頁樣式
*
*/
private function n($show=true){
$this->pstyle[]=$this->arg['page']>=$this->totalpage&&$show? $this->cfg['text'][2]:"<a href=\"{$this->buildurl($this->arg['page']+1)}\">{$this->cfg['text'][2]}</a>";
}
/**
* 搜索引擎分頁
*
* @param int $limit 最大左右偏移量之和
* @param int $lstyle 樣式
* @return string 樣式字符串
*
*/
private function l($limit=7,$lstyle=1){
$a=floor($limit/2); //左右偏移量
$l=$this->arg['page']-$a;$r=$this->arg['page']+$a; //默認偏移量
$l<$a-1&&$r+=1-$l;//如果左不足
if($r>$this->totalpage){//如果右不足
$l-=$r-$this->totalpage;
$r=$this->totalpage;
}
$l<1&&$l=1;
//輸出
switch ($lstyle){
case '0':
for($i=$l;$i<=$r;$i++){
$output.=' '.($this->arg['page']==$i? str_replace('{$page}',$i,$this->cfg['listtpl']):"<a href=\"{$this->buildurl($i)}\">".str_replace('{$page}',$i,$this->cfg['listtpl'])."</a>").' ';
}
break;
case '1':
$l>1&&$output="<a href=\"{$this->buildurl(1)}\">".str_replace('{$page}',1,$this->cfg['listtpl'])."</a>";
$l>2&&$output.='...';
for($i=$l;$i<=$r;$i++){
$output.=' '.($this->arg['page']==$i? "<strong>$i</strong>":"<a href=\"{$this->buildurl($i)}\">".str_replace('{$page}',$i,$this->cfg['listtpl'])."</a>").' ';
}
$r<$this->totalpage-1&&$output.='...';
$r<=$this->totalpage-1&&$output.="<a href=\"{$this->buildurl($this->totalpage)}\">".str_replace('{$page}',$this->totalpage,$this->cfg['listtpl'])."</a>";
}
$this->pstyle[]=$output;
}
/**
* 取得記錄總數
*
*/
private function t(){
$this->pstyle[]=$this->cfg['total'];
}
/**
* 取得總頁數
*
*/
private function tp(){
$this->pstyle[]=$this->totalpage;
}
/**
* 創建完整分頁樣式
*
* @param string $space 各部分合並間隔符號
* @return string 完整分頁字符串
*
*/
public function create($space=' '){
foreach($this->cfg['tpl'] as $arg){
if(is_array($arg)){
if(method_exists($this,$func=array_shift($arg))){
call_user_func_array(array($this,$func),$arg);
}
else{
$this->pstyle[]=$func;
}
}
else{
if(method_exists($this,$arg)){
call_user_func(array($this,$arg));
}
else{
$this->pstyle[]=$arg;
}
}
}
return implode($space,$this->pstyle);
}
}
/*
調用方法:
例1:默認調用
$pageination=new pagination(array(total=>200)); //必選參數total
echo $pageination->create();
例2:設置更多參數
$pageination=new pagination(array(total=>200,pagesize=>30,text=>array(|<,<,>,>|),tpl=>array(t,'條/',tp,'頁',l,s))); //必選參數total,tpl內數組對應類中的函數名,如果函數不存在則按順序原樣顯示出來
echo $pageination->create();
例3:複雜調用
$pageination=new pagination(array(total=>200,pagesize=>30,text=>array(|<,<,>,>|),tpl=>array(t,'條/',tp,'頁',array(l,9,0),s)));
echo $pageination->create();
例4:ajax 調用
$pageination=new pagination(array(total=>200,ajax=>'loadlist')); //將在頁的鏈接上使用javascript loadlist函數 帶有一個參數是頁數 即調用如 loadlist(5).
echo $pageination->create();
例5:靜態頁調用
$pageination=new pagination(array(total=>200,page=>1,htmltpl=>'list{$page}.shtml')); //將生成模板格式靜態分頁 $pageination->arg[page]=n 來改變當前頁
echo $pageination->create();
注:以上方法除了PHP翻頁(默認)方式,其他方式均未測試,有問題歡迎與我聯繫,大家一起探討完善
*/
?>