2008年4月1日 星期二

php分頁function

前一陣子在逛逛yahoo的知識+的時候發現還不少人在問分頁的問題,我就來分享一下自己寫的分頁function吧 ```php function Pager($pager_options = []) { //因為無法使用可變變數取得$_開頭的超級全域變數,所以先利用參考的方式值到自定義的變數 $post = &$_POST; $get = &$_GET; $request = &$_REQUEST; if (empty($pager_options['totalItems'])) { die('未設置 totalItems'); } //取得分頁變數的方式可為request、get、post $method = (empty($pager_options['method'])) ? 'request' : $pager_options['method']; $method = strtolower($method); $method = $$method; //取得分頁變數,例如pageVar為pageID,$method為post則分頁的變數則為$_POST['pageID'] $pageVar = (empty($pager_options['pageVar'])) ? 'pageID' : $pager_options['pageVar']; //設定每頁幾筆 $pager_options['perPage'] = (empty($pager_options['perPage'])) ? 10 : $pager_options['perPage']; //顯示同一個頁面顯示幾頁 $pager_options['delta'] = (empty($pager_options['delta'])) ? 10 : $pager_options['delta']; //取得當前頁數 $pager_options['current'] = (empty($method[$pageVar])) ? 1 : $method[$pageVar]; //設定link的前置網址 $pager_options['link'] = (empty($pager_options['link'])) ? $_SERVER['PHP_SELF'] : $pager_options['link']; //取得總筆數 $total = ceil($pager_options['totalItems'] / $pager_options['perPage']); if ($pager_options['current'] > $total && $total != 0) { $pager_options['current'] = $total; } $pager_options['page_numbers'] = [ 'current' => $pager_options['current'], 'total' => $total, ]; $pager_options['deltaStart'] = floor(($pager_options['page_numbers']['current'] - 1) / $pager_options['delta']) * $pager_options['delta'] + 1; $pager_options['start'] = ($pager_options['current'] - 1) * $pager_options['perPage']; $pager_options['offset'] = $pager_options['perPage']; $pager_options['from'] = $pager_options['start'] + 1; $pager_options['to'] = $pager_options['from'] + $pager_options['perPage'] - 1; return $pager_options; } //改利用Pager做查詢會幫你完成分頁 //可用參數 /* perPage 每頁幾筆 delta 顯示頁數 link a標籤上的連結 pageVar 分頁的參數 method 取得頁數變數的方法可以為post,get,request totalItems 總筆數 */ $page = Pager([ 'perPage' => 10, 'delta' => 10, 'link' => 'index.php?op=default', 'pageVar' => 'page', 'totalItems' => 100, ]); var_dump($page); //回傳的參數 /* $page['perPage']; 每頁幾筆 $page['delta']; 顯示頁數 $page['link']; a標籤上的連結 $page['totalItems']; 總筆數 $page['page_numbers']['current']; 目前所在頁數 $page['page_numbers']['total']; 總頁數 $page['deltaStart']; $page['start']; mysql limit的start值 $page['offset']; mysql limit的offset值 $page['from']; $page['to']; */ ``` 原則上這個分頁是我從之前寫的程式抽出來的,原本是和phplib的db物件做結合,當然了,也可以拿去和其他的DB物件做結合,看大家怎麼變化囉 ```php //載入phplib的db物件 require_once dirname(__FILE__).'/../phplib/db_mysql.inc'; //為db物件增加method並增加修改語系問題 class MySQL extends DB_MySQL { /* public: connection parameters */ public $Host = DBLOCATION; public $Database = DBNAME; public $User = DBUSER; public $Password = DBPW; public function query($sql) { //在每次查詢時先送出定義mysql語系的語法,如果是mysql4.0以下的話請把這一段拿掉 parent::query('set names utf8'); return parent::query($sql); } //取得總筆數 public function getTotalItems($sql) { //正規表示將select語法改為 select count(*) from table $countSql = preg_replace('/(ORDER|LIMIT)(.*)/i', '', $sql); $count_pattern = '/SELECT\s(.*)\sfrom\s/imsU'; if (preg_match($count_pattern, $countSql, $matched)) { $groupby_pattern = '/(GROUP\s?BY(.*))/ism'; if (preg_match($groupby_pattern, $countSql, $matched2)) { $countSql = str_replace($matched2[1], '', $countSql); $countSql = str_replace($matched[1], sprintf('COUNT(DISTINCT %s) as totalItems', $matched2[2]), $countSql); } else { $countSql = str_replace($matched[1], 'COUNT(*) as totalItems', $sql); } $this->query($countSql); $this->next_record(); return $this->Record['totalItems']; } else { return 0; } } /* * 新增取得分頁的方法 * 原本在phplib時是使用$db->query($sql); * 查詢成功則會回傳true,失敗則回傳false * 如果要分頁的話就利用 * 原本在phplib時是使用$db->Pager($sql); * 查詢成功則會回傳分頁資訊,失敗則回傳false */ public function Pager($sql, $pager_options = []) { //因為無法使用可變變數取得$_開頭的超級全域變數,所以先利用參考的方式值到自定義的變 $post = &$_POST; $get = &$_GET; $request = &$_REQUEST; //取得分頁變數的方式可為request、get、post $method = (empty($pager_options['method'])) ? 'request' : $pager_options['method']; $method = strtolower($method); $method = $$method; //取得分頁變數,例如pageVar為pageID,$method為post則分頁的變數則為$_POST['pageID'] $pageVar = (empty($pager_options['pageVar'])) ? 'pageID' : $pager_options['pageVar']; //設定每頁幾筆 $pager_options['perPage'] = (empty($pager_options['perPage'])) ? 10 : $pager_options['perPage']; //顯示同一個頁面顯示幾頁 $pager_options['delta'] = (empty($pager_options['delta'])) ? 10 : $pager_options['delta']; //取得當前頁數 $pager_options['current'] = (empty($method[$pageVar])) ? 1 : $method[$pageVar]; //設定link的前置網址 $pager_options['link'] = (empty($pager_options['link'])) ? $_SERVER['PHP_SELF'] : $pager_options['link']; //取得總筆數 $pager_options['totalItems'] = (empty($pager_options['totalItems'])) ? $this->getTotalItems($sql) : $pager_options['totalItems']; $total = ceil($pager_options['totalItems'] / $pager_options['perPage']); if ($pager_options['current'] < 1) { $pager_options['current'] = 1; } elseif ($pager_options['current'] > $total && $pager_options['current'] != 1) { $pager_options['current'] = $total; } $pager_options['page_numbers'] = [ 'current' => $pager_options['current'], 'total' => $total, ]; $pager_options['deltaStart'] = floor(($pager_options['page_numbers']['current'] - 1) / $pager_options['delta']) * $pager_options['delta'] + 1; $pager_options['start'] = ($pager_options['current'] - 1) * $pager_options['perPage']; $pager_options['offset'] = $pager_options['perPage']; $pager_options['from'] = $pager_options['start'] + 1; $pager_options['to'] = $pager_options['from'] + $pager_options['perPage'] - 1; $limitSql = sprintf('%s LIMIT %s , %s', $sql, $pager_options['start'], $pager_options['offset']); if ($this->query($limitSql)) { return $pager_options; } else { return false; } } } //再次繼承 class DB extends MySQL { public $Host = 'localhost'; public $Database = 'test'; public $User = 'root'; public $Password = ''; } ``` 使用方法 ```php $db = new DB; $sql = 'SELECT * FROM account ORDER BY account'; $results = []; $page = $db->Pager($sql, [ 'perPage' => 10, 'delta' => 10, 'link' => 'index.php?op=default', 'pageVar' => 'page', ]); if ($page) { while ($db->next_record()) { $results[] = $db->Record; } } print_r($page); print_r($result); ```