function getPageRange($currentPage, $totalPages, $displaySize = 10) {
if ($totalPages <= 0 || $displaySize <= 0) {
return array();
} elseif ($displaySize > $totalPages) {
$startPage = 1;
$endPage = $totalPages;
} else {
if ($currentPage % $displaySize === 0) {
$startPage = $currentPage - $displaySize + 1;
} else {
while (($currentPage % $displaySize)) {
--$currentPage;
}
$startPage = $currentPage + 1;
}
if ($startPage <= 0) {
$startPage = 1;
}
$endPage = $startPage + $displaySize - 1;
if ($endPage > $totalPages) {
$endPage = $totalPages;
$startPage = $endPage - $displaySize + 1;
}
}
return range($startPage, $endPage);
}函數getPageRange接受三個參數,當前頁$currentPage,總頁數$totalPages,和翻頁區間長度$displaySize,默認是10。根據這三個參數,函數getPageRange會生成一個適當的包含了$currentPage的翻頁區間。首先,我們需要排除非法的參數值,對於總頁數或區間長度小於零的情況,須加以檢查。
然後,我們考察靜態劃分的思路。如前所述,給定翻頁區間長度後,便可用總頁數除以長度,得到區間個數。與此同時,我們可分析得知並不是所有區間都含有相同的頁數,在極端情況下,還會出現總頁數小於給定的翻頁區間長度,那麼劃分或切割的結果將永遠只有一個區間。幸運的是,這不會給我們的核心算法帶來什麼干擾,但我們仍須重視代碼的健壯性。所以,我們先考慮極端情況,在運用算法解決核心問題之前,先迅速捕捉只有一頁的區間。
接下來,我們便可以看看區間的固有屬性了。每個動態切割的區間,都有一個起始頁和一個尾頁;由於區間彼此存在先後順序,所以在經過靜態劃分後,我們始終會得到第一個(首)區間和最後一個(尾)區間,若首尾區間重合,則說明總頁數小於給定的翻頁區間長度。無論如何,算法需要解決的關鍵問題是如何找到區間的起始頁和尾頁,一旦確定這兩個元素,便可以使用PHP內置的range函數生成區間內的全部頁碼。
算法利用當前頁$currentPage和翻頁區間長度$displaySize做比較,來判斷當前頁在區間內所處的位置,進而推導出區間起始頁和尾頁與當前頁的偏移量。為了做到完美無缺,我們還要考慮邊界溢出的問題,這也非常簡單,只需判斷起始頁和尾頁是否介於1和總頁數之間即可。
至此,對於代碼的分析已經完成。我們來看一下算法的時間效率,通俗地說,算法中的基本操作是求模,算法的執行時間取決於$currentPage與$displaySize的差值,差值越大,則求模次數越多、執行時間越長,呈線性結構。而實際的執行結果則是在瞬間完成的。
下面,我們來結合上面的Google搜索結果頁,利用getPageRange函數生成一個翻頁區間,輸入所需參數:
print_r(implode(',', getPageRange(18, 27, 20)));得到的結果是:
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20大家會發現這和Google搜索結果頁顯示的完全不一樣。對,因為Google的翻頁區間把當前頁強制設置在中間位置上了!嗯,不要灰心,我們仍可以利用getPageRange函數得到與之相匹配的結果,只需把問題再分解一下:
print_r(implode(',', array_merge(getPageRange(17, 17, 10), getPageRange(27, 27, 10))));得到的結果是:
8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27