在平常開發的業務環境中,咱們通常都會使用 MySQL 語句來實現分頁的功能。可是,每每也有些數據並很少,或者只是獲取 PHP 中定義的一些數組數據時須要分頁的功能。這時,咱們其實不須要每次都去查詢數據庫,能夠在一次查詢中把全部的數據取出來,而後在 PHP 的代碼層面進行分頁功能的實現。今天,咱們就來學習一下能夠實現這個能力的一些函數技巧。php
首先,咱們仍是準備好測試數據。前端
$data = [ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', ]; // $p = $_GET['p']; $p = 2; $currentPage = $p <= 1 ? 0 : $p - 1; $pageSize = 3; $offset = $currentPage * $pageSize;
假設 \$data 就是從數據庫中取出的所有數據,或者就是咱們寫死在 PHP 代碼中的數據。而後咱們設定 $p 爲接收到的請求參數,當前訪問的是第二頁。$currentPage 是用於查詢偏移量的修正,在代碼開發的世界中,下標索引都是從0開始的,因此咱們須要對接收到的參數進行減一的操做。固然,你也能夠設定前端傳遞的參數就是以 0 爲第一頁的。這個就很少解釋了,相信你們只要正式的學習或者參與過開發項目都會明白它的意思。git
而後咱們定義了當前頁面所顯示的信息條數 $pageSize ,也就是隻獲取 3 條數據。最後,咱們計算了一下偏移量,也就是相似於 MySQL 的 LIMIT 中的那個參數。它的做用就是告訴咱們從第幾條開始查詢,而後配合 $pageSize 查詢幾條。這樣咱們就能夠得到當前頁面對應的數據了。(貌似把分頁的原理都講了一下)github
第一個也是最基礎和最多見的分頁方式,就是使用 array_slice() 函數來實現。它的做用是從數組中截取出一段內容來並返回這段內容的數組。數據庫
var_dump(array_slice($data, $offset, $pageSize)); // array(3) { // [0]=> // string(1) "D" // [1]=> // string(1) "E" // [2]=> // string(1) "F" // }
array_slice() 函數須要三個參數,第二個參數就是偏移量,第三個參數是查詢幾條數據。其中,第三個參數是可選的,不填的話就會把當前設定的偏移量以後的數據所有顯示出來。是否是和咱們的 MySQL 查詢語句如出一轍。沒錯,他們自己就是相似的操做。數組
array_chunk() 函數則是根據一個數值參數將一個數組進行分組,也就是將數組分割成一段一段的子數組。咱們就能夠根據分割後的數組來獲取指定下標的子數組內容,這些內容就是當前的頁面須要展現的數據了。函數
$pages = array_chunk($data, $pageSize); var_dump($pages); // array(4) { // [0]=> // array(3) { // [0]=> // string(1) "A" // [1]=> // string(1) "B" // [2]=> // string(1) "C" // } // [1]=> // array(3) { // [0]=> // string(1) "D" // [1]=> // string(1) "E" // [2]=> // string(1) "F" // } // [2]=> // array(3) { // [0]=> // string(1) "G" // [1]=> // string(1) "H" // [2]=> // string(1) "I" // } // [3]=> // array(2) { // [0]=> // string(1) "J" // [1]=> // string(1) "K" // } // } var_dump($pages[$currentPage]); // array(3) { // [0]=> // string(1) "A" // [1]=> // string(1) "B" // [2]=> // string(1) "C" // }
這段代碼咱們輸出了分割後的數組內容,而後須要的是第二頁也就是下標爲 1 的數據,直接經過分割後的數組就能夠方便地獲取到所須要的內容了。使用這個函數來作數組分頁的功能很是地簡單直觀,並且它不須要去計算偏移量,直接就是使用當前頁 $currentPage 和 $pageSize 就能夠完成對於數據的分組了,很是推薦你們使用這個函數來進行相似的操做。學習
最後咱們要學習到的是使用一個迭代器類來實現數組分頁的能力,這個使用的就比較少了,估計都沒什麼人知道,但其實 LimitIterator 類在 PHP5.1 時就已經提供了。它的做用是容許遍歷一個 Iterator 的限定子集的元素。也就是說,若是咱們的代碼中使用了迭代器模式,實現了迭代器接口,那麼這些迭代器類均可以使用這個類進行分頁操做。測試
foreach (new LimitIterator(new ArrayIterator($data), $offset, $pageSize) as $d) { var_dump($d); } // string(1) "D" // string(1) "E" // string(1) "F"
它須要的實例化構造參數包含3個,第一個是一個迭代器對象,因爲數組不是迭代器對象,因此咱們使用 ArrayIterator 實例將咱們的數組數據轉化爲一個迭代器對象。後面兩個參數就是偏移量和數據數量了,這個和 array_slice() 函數是相似的,不過不一樣的是,它的偏移量參數也是能夠選的。若是咱們不給後面的可選參數的話,那麼它將遍歷全部的數據。.net
foreach (new LimitIterator(new ArrayIterator($data)) as $d) { var_dump($d); } // string(1) "A" // string(1) "B" // string(1) "C" // string(1) "D" // string(1) "E" // string(1) "F" // string(1) "G" // string(1) "H" // string(1) "I" // string(1) "J" // string(1) "K"
接下來,咱們看看若是參數錯誤,也就是偏移量或者所需的數據量大小有問題的話,這些操做將會有什麼樣的表現。
var_dump(array_slice($data, $offset, 150)); // array(8) { // [0]=> // string(1) "D" // [1]=> // string(1) "E" // [2]=> // string(1) "F" // [3]=> // string(1) "G" // [4]=> // string(1) "H" // [5]=> // string(1) "I" // [6]=> // string(1) "J" // [7]=> // string(1) "K" // } var_dump(array_slice($data, 15, $pageSize)); // array(0) { // }
array_slice() 函數對於偏移量錯誤的兼容就是展現一個空的數組。而數據量超標的話則會展現全部偏移量以後的數據。
var_dump($pages[15]); // NULL
array_chunk() 對於下標不存在的數據固然就是返回一個 NULL 值啦。
foreach (new LimitIterator(new ArrayIterator($data), $offset, 150) as $d) { var_dump($d); } // string(1) "D" // string(1) "E" // string(1) "F" // string(1) "G" // string(1) "H" // string(1) "I" // string(1) "J" // string(1) "K" foreach (new LimitIterator(new ArrayIterator($data), 15, $pageSize) as $d) { var_dump($d); } // Fatal error: Uncaught OutOfBoundsException: Seek position 15 is out of range
LimitIterator 則是對於偏移量錯誤的數據直接返回錯誤異常信息了。這也是類模式處理的好處,有錯誤都會以異常的形式進行返回,方便咱們對異常進行後續的處理。
其它的測試你們還能夠自行檢測,好比偏移是 0 或者是負數的狀況,數據量是 0 或者是負數的狀況。這些我就很少寫了,你們能夠根據已有的知識先猜測一下結果會是什麼樣的,而後再本身寫代碼驗證一下結果是符合本身的預期,這樣學習的效果會很是棒哦!(在下方測試代碼連接中有測試,結果裏面是有坑的哦)
一個功能使用了三種方式來實現,這就是代碼的魅力。至於哪一個好哪一個壞咱們很少作評價,一切都是以業務爲核心來進行選取。相似的功能雖然說並不常見,但不少項目裏都會遇到,好比說後臺用戶組管理就會很是常見,通常來講後臺用戶分組若是不是特別大型的 ERP 項目都不會不少,但有時候也會達到須要分頁的程度,這時候,咱們就能夠考慮考慮使用今天所學的知識來作咯!
測試代碼:
參考文檔:
https://www.php.net/manual/zh/function.array-slice.php
https://www.php.net/manual/zh/function.array-chunk.php
各自媒體平臺都可搜索【硬核項目經理】