在日常開發的業務環境中,我們一般都會使用 MySQL 陳述句來實作分頁的功能,但是,往往也有些資料并不多,或者只是獲取 PHP 中定義的一些陣列資料時需要分頁的功能,這時,我們其實不需要每次都去查詢資料庫,可以在一次查詢中把所有的資料取出來,然后在 PHP 的代碼層面進行分頁功能的實作,今天,我們就來學習一下可以實作這個能力的一些函式技巧,
首先,我們還是準備好測驗資料,
$data = https://www.cnblogs.com/zyblog-coder/archive/2021/06/14/['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 為第一頁的,這個就不多解釋了,相信大家只要正式的學習或者參與過開發專案都會明白它的意思,
然后我們定義了當前頁面所顯示的資訊條數 $pageSize ,也就是只獲取 3 條資料,最后,我們計算了一下偏移量,也就是類似于 MySQL 的 LIMIT 中的那個引數,它的作用就是告訴我們從第幾條開始查詢,然后配合 $pageSize 查詢幾條,這樣我們就可以獲得當前頁面對應的資料了,(貌似把分頁的原理都講了一下)
array_slice
第一個也是最基礎和最常見的分頁方式,就是使用 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
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
最后我們要學習到的是使用一個迭代器類來實作陣列分頁的能力,這個使用的就比較少了,估計都沒什么人知道,但其實 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() 函式是類似的,不過不同的是,它的偏移量引數也是可以選的,如果我們不給后面的可選引數的話,那么它將遍歷所有的資料,
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://github.com/zhangyue0503/dev-blog/blob/master/php/202008/source/PHP%E4%B8%AD%E7%9A%84%E6%95%B0%E7%BB%84%E5%88%86%E9%A1%B5%E5%AE%9E%E7%8E%B0%EF%BC%88%E9%9D%9E%E6%95%B0%E6%8D%AE%E5%BA%93%EF%BC%89.php
參考檔案:
https://www.php.net/manual/zh/function.array-slice.php
https://www.php.net/manual/zh/function.array-chunk.php
https://www.php.net/limititerator
關注公眾號:【硬核專案經理】獲取最新文章
添加微信/QQ好友:【xiaoyuezigonggong/149844827】免費得PHP、專案管理學習資料
知乎、公眾號、抖音、頭條搜索【硬核專案經理】
B站ID:482780532
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/287287.html
標籤:其他
