一. 思路整理
實現一個數據分頁功能,需要有數據的總條數,每頁展示的條數,和當前在第幾頁這三個參數
通過⌈總條數/每頁展示的條數⌉可以得到總頁數,比如某留言板有101條留言,每頁展示10條,一那就需要11個頁面進行展示
數據分頁核心就是通過SQL的limit函數來控制當前頁顯示第幾條到第幾條,比如第一頁limit(0,10),就是第1條到第10條,第二頁是limit(11,10),就是第11條到第20條 . . . . . .
用當(前頁數-1)*每頁顯示條數+1就可以得到limit的第一個參數,limit的第二個參數就是當前頁顯示的數據條數.
二. 3個必要參數
當前頁$page使用get方式在url中傳入,修改page屬性就可以跳轉頁面,點擊上一頁下一頁等操作都是通過修改page實現的
每頁展示條數$listRow在實例化page類時傳參的方式定義,通過修改l$istrow就可以設置每頁顯示的信息條數:
顯示的總條數$total通過查詢數據庫獲得:
創建一個數據表messageboard,為了方便只設置id title兩個字段
創建數據庫連接
$pdoObj = new PDO("mysql:host=localhost;dbname=zhangkwebsite", 'root', 'root');
$pdoObj->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
獲取數據的總條數$ncount
$query=$pdoObj->query("select count(*) from messageboard");
$val=$query->fetch(PDO::FETCH_ASSOC); $ncount=$val['count(*)'];
三. 數據分頁類
創建一個數據分頁類page,在類中定義好需要使用的變量
class page{ private $total;//總記錄數 private $listRows;//每頁顯示行數 private $limit;//sql語句的limit限制 private $uri;//去掉page屬性的uri private $pageNum;//總頁數 private $listNum;//頁碼數量
總記錄數和每頁顯示的條數在用戶實例化類時設置
public function __construct($total,$listRows=10){ $this->total=$total; $this->listRows=$listRows;
當前頁顯示的記錄$limit
limit (前頁數-1)*每頁顯示條數+1,每頁總條數 和前面的例子完全相同
private function setLimit() { return 'Limit' .' '.($this->page - 1) * $this->listRows .','."{$this->listRows}"; }
setLimit()的返回值將保存在私有變量$limit中,使用__get函數為用戶提供一個調用的接口
function __get($args) { if ($args=="limit"){ return $this->limit; } else return null; }
這個字符串在用戶查詢時拼接在sql語句中
$p=new page($ncount,5);
$query=$pdoObj->query("select * from messageboard {$p->limit}");
獲取當前頁的第一條和最后一條,這個沒什么難度
private function start(){ if($this->total==0) return 0; else return ($this->page - 1) * $this->listRows+1; } private function end(){ return min($this->total,$this->page*$this->listRows); }
pagegetUri()方法:去掉鏈接中的page屬性
因為$page在url中,不能直接改變它的值,需要通過字符串的方式,先將他的值去掉,然后再拼接上:
//將uri的page去掉
private function getUri(){
//第一步.獲取當前頁面的url,檢查是否由如果沒有問號,加上問號
$uri=$_SERVER['REQUEST_URI'].(strpos($_SERVER['REQUEST_URI'],'?')?'':'?'); //parse_url將當前url轉換成數組格式 $parse=parse_url($uri); //第二步.去掉url里的page屬性,然后重新拼接起來 if(isset($parse['query'])){ parse_str($parse['query'],$params); unset($params['page']); } $url=$parse['path'].'?'.http_build_query($params); //parse_url:將url轉成有path和query兩個屬性的數組 //parse_str("page=10",$param)將字符串解析成多個變量存入數組$param中 //http_build_query將數組類型轉為字符串類型 return $uri; }
函數的返回值將賦給$uri變量
點擊跳轉的功能
用字符串拼接出一個鏈接,打印在屏幕上,需要注意的是鏈接的地址:
這個時候$uri就有用了,首頁鏈接的地址就是$uri + '&page=1'
//首頁 private function first(){ if ($this->page==1) return ''; else return "<a href='{$this->uri}&page=1'>首頁</a> "; }
尾頁,鏈接的地址就是$uri + '&page=頁數'
<a href='{$this->uri}&page=$lastpage'>尾頁</a>
上一頁下一頁的鏈接就是當前的page+1,當前的page-1,與首頁末頁的區別就是要做一下判斷,如果當前是第一頁就不能點擊上一頁,當前是最后一頁就不能點擊下一頁
為了體現良好模塊化,鏈接的文字內容應該封裝在一個字符串中:
private $config=array("header"=>"新聞","unit"=>"條","prev"=>"上一頁","next"=>"下一頁","first"=>"首頁","last"=>"尾頁");
代碼就是這樣:
//上一頁 private function prev() { if ($this->page == 1) return "{$this->config['prev']}"; else { $prevpage=$this->page-1; return "<a href='{$this->uri}&page=$prevpage'>{$this->config['prev']}</a> "; } }
頁碼設置
三個字符串,前一個是循環輸出頁碼數量的一半向下取整,中間是當前頁不加鏈接,后一個循環輸出是當前頁之后的一半向下取整
//設置頁碼: //第一個循環,顯示總數向下取整floor(5)=2次,顯示當前頁-2,當前頁-1 //第二個循環,顯示總數向下取整floor(5)=2次,當前頁+1,當前頁+2 private function partList(){ $linkpage=''; $inum=floor($this->listNum/2); for($i=$inum;$i>=1;$i--){ $page=$this->page-$i; if($page>=1){ $linkpage.="<a href='{$this->uri}&page={$page}'>{$page}</a> "; } } $linkpage.="{$this->page} "; for($i=1;$i<=$inum;$i++){ $listpage=$this->page+$i; if ($listpage<=$this->pageNum){ $linkpage.="<a href='{$this->uri}&page={$listpage}'>{$listpage}</a> "; } } return $linkpage; }
跳轉到第X頁功能
這個要借助js實現:
點擊跳轉按鈕時,觸發事件函數:
獲取input框中的內容,將其作為$page的值拼接到uri上
然后通過location方法跳轉到拼接好的uri對應的頁面
private function gopage(){ $go="到第<input type='text' class='goinput' style='width:28px;'>頁 <button class='goBn'>跳轉</button>"; $go.="<script> var goBn = document.querySelector('.goBn'); goBn.onclick=function(){ var go = document.querySelector('.goinput').value; if(go<{$this->pageNum}&&go>0){ var gohref = new String(\"{$this->uri}&page=\"); var gohref=gohref+go; location=gohref; } } </script>"; return $go; }
四.完整的代碼如下:
分頁類page.php
<?php class page{ private $total;//總記錄數 private $listRows;//每頁顯示行數 private $uri;//uri private $page;//當前頁 private $limit;//sql語句的limit限制 private $pageNum;//總頁數 private $listNum=5;//頁碼數 private $config=array("header"=>"新聞","unit"=>"條","prev"=>"上一頁","next"=>"下一頁","first"=>"首頁","last"=>"尾頁"); public function __construct($total,$listRows=10){ $this->total=$total; $this->listRows=$listRows; $this->uri=$this->getUri(); $this->page=empty($_GET['page'])?1:$_GET['page']; //獲取頁數:總數除以每頁uri記錄數向上取整 $this->pageNum=ceil($this->total/$this->listRows); $this->limit=$this->setLimit(); } function __get($args) { if ($args=="limit"){ return $this->limit; } else return null; } //將uri的page去掉 private function getUri(){ //獲取當前頁面的url,檢查是否有問號,如果沒有問號,加上問號 $uri=$_SERVER['REQUEST_URI'].(strpos($_SERVER['REQUEST_URI'],'?')?'':'?'); //parse_url將url轉換成數組格式 $parse=parse_url($uri); //去掉url里的page屬性,然后重新拼接起來 if(isset($parse['query'])){ parse_str($parse['query'],$params); unset($params['page']); } $url=$parse['path'].'?'.http_build_query($params); //parse_url:將url轉成有path和query兩個屬性的數組 //parse_str("page=10",$param)將字符串解析成多個變量存入數組$param中 //http_build_query將數組類型轉為字符串類型 return $url; } //當前頁從第幾個開始顯示,顯示多少個 private function setLimit() { return 'Limit' .' '.($this->page - 1) * $this->listRows .','."{$this->listRows}"; } //獲取當前頁的第一條和最后一條顯示的行號 private function start(){ if($this->total==0) return 0; else return ($this->page - 1) * $this->listRows+1; } private function end(){ return min($this->total,$this->page*$this->listRows); } //首頁 private function first(){ if ($this->page==1) return ''; else return "<a href='{$this->uri}&page=1'>{$this->config['first']}</a> "; } //上一頁 private function prev() { if ($this->page == 1) return "{$this->config['prev']}"; else { $prevpage=$this->page-1; return "<a href='{$this->uri}&page=$prevpage'>{$this->config['prev']}</a> "; } } //下一頁 private function next() { if ($this->page == $this->pageNum) return "{$this->config['next']}"; else { $nextpage=$this->page+1; return "<a href='{$this->uri}&page=$nextpage'>{$this->config['next']}</a> "; } } //尾頁 private function last() { if ($this->page == $this->pageNum) return ''; else { $lastpage=$this->pageNum; return "<a href='{$this->uri}&page=$lastpage'>{$this->config['last']}</a> "; } } //設置頁碼: //寫兩個循環,前一個是當前頁之前的一半,中間是當前頁不加鏈接,后一個是當前頁之后的一半 //第一個循環,顯示總數向下取整floor(5)=2次,顯示當前頁-2,當前頁-1 //第二個循環,顯示總數向下取整floor(5)=2次,當前頁+1,當前頁+2 private function partList(){ $linkpage=''; $inum=floor($this->listNum/2); for($i=$inum;$i>=1;$i--){ $page=$this->page-$i; if($page>=1){ $linkpage.="<a href='{$this->uri}&page={$page}'>{$page}</a> "; } } $linkpage.="{$this->page} "; for($i=1;$i<=$inum;$i++){ $listpage=$this->page+$i; if ($listpage<=$this->pageNum){ $linkpage.="<a href='{$this->uri}&page={$listpage}'>{$listpage}</a> "; } } return $linkpage; } private function gopage(){ $go="到第<input type='text' class='goinput' style='width:28px;'>頁 <button class='goBn'>跳轉</button>"; $go.="<script> var goBn = document.querySelector('.goBn'); goBn.onclick=function(){ var go = document.querySelector('.goinput').value; if(go<{$this->pageNum}&&go>0){ var gohref = new String(\"{$this->uri}&page=\"); var gohref=gohref+go; location=gohref; } } </script>"; return $go; } //顯示的當前頁面內容 function fpage($checkHtml=array(1,2,3,4,5,6,7,8,9,10)){ $html[1]="共有{$this->total}{$this->config['unit']}{$this->config['header']} "; $html[2]="本頁{$this->start()}條到{$this->end()}條 "; $html[3]="當前為{$this->page}/{$this->pageNum}頁 "; $html[4]="{$this->first()}"; $html[5]="{$this->prev()}"; $html[6]="{$this->next()}"; $html[7]="{$this->last()} "; $html[8]="{$this->partList()} "; $html[9]="{$this->gopage()}"; $html[10]=" "; $showhtml=''; foreach($checkHtml as $i){ $showhtml.=$html[$i]; } return $showhtml; } }
messageboard.php
<?php header("Content-type: text/html; charset=utf-8"); include 'page.php'; try { $pdoObj = new PDO("mysql:host=localhost;dbname=zhangkwebsite", 'root', 'root'); $pdoObj->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); }catch(PDOException $p){ echo '數據庫連接失敗'.$p->getMessage(); } try{ echo '<table align="center" border="1" width="1000">' ."<tr><th colspan='2'>新聞瀏覽</th></tr>"; $query=$pdoObj->query("select count(*) from messageboard"); $val=$query->fetch(PDO::FETCH_ASSOC); $ncount=$val['count(*)']; $p=new page(100,5); $query=$pdoObj->query("select * from messageboard {$p->limit}"); while($val=$query->fetch(PDO::FETCH_ASSOC)){ echo '<tr>'; echo '<td>'.$val["id"].'</td>'; echo '<td>'.$val["title"].'</td>'; echo '</tr>'; } echo "<tr><td colspan='2' style='text-align: right'>{$p->fpage()}</td></tr></table>"; } //query("select * from account where account=$XX and pwd=YY"); //query("select * from account where account=:account and pwd=:pwd",['account'=>$xx,'']); //query("select * from account where account=? and pwd=?"); //sprintf(select * from account where account=%d and pwd=%s,['']) catch(PDOException $e){ echo '錯誤'.$e->getMessage(); }