First, we still prepare the test data.
$data = [ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', ]; // $p = $_GET['p']; $p = 2; $currentPage = $p a0411447250001f7e9e6d7c13beb845c // string(1) "D" // [1]=> // string(1) "E" // [2]=> // string(1) "F" // }
array_slice() function requires three parameters, the second parameter is the offset, and the third parameter is to query several pieces of data. Among them, the third parameter is optional. If not filled in, all data after the currently set offset will be displayed. Is it exactly the same as our MySQL query statement? Yes, they themselves are similar operations.
array_chunk
array_chunk() function groups an array according to a numerical parameter, that is, splits the array into sub-arrays. We can obtain the subarray contents of the specified subscript based on the divided array. These contents are the data that need to be displayed on the current page.
$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" // }
In this code, we output the contents of the divided array, and then what we need is the second page, which is the data with subscript 1. We can easily obtain the required information directly through the divided array. content. Using this function to do array paging is very simple and intuitive, and it does not need to calculate the offset. You can directly use the current page $currentPage and $pageSize to complete the grouping of data. It is highly recommended that you use this function. Do something similar.
LimitIterator
The last thing we need to learn is the ability to use an iterator class to implement array paging. This is used less often, and probably no one knows about it, but in fact the LimitIterator class It has been provided in PHP5.1. Its purpose is to allow iteration over a restricted subset of the elements of an Iterator. In other words, if our code uses the iterator pattern and implements the iterator interface, then these iterator classes can use this class for paging operations.
foreach (new LimitIterator(new ArrayIterator($data), $offset, $pageSize) as $d) { var_dump($d); } // string(1) "D" // string(1) "E" // string(1) "F"
It requires 3 instantiation construction parameters. The first one is an iterator object. Since the array is not an iterator object, we use the ArrayIterator instance to convert our array data into an iterator object. . The next two parameters are the offset and the number of data. This is similar to the array_slice() function, but the difference is that its offset parameter is also optional. If we do not give the following optional parameters, then it will traverse all the data.
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"
Performance when parameters are wrong
Next, let’s take a look at what will happen to these operations if the parameters are wrong, that is, there is a problem with the offset or the required data size. Such performance.
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() function is compatible with offset errors by displaying an empty array. If the amount of data exceeds the standard, all data after the offset will be displayed.
var_dump($pages[15]); // NULL
array_chunk() will of course return a NULL value for data whose subscript does not exist.
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 directly returns error exception information for data with wrong offset. This is also the benefit of class mode processing. Any errors will be returned in the form of exceptions, which facilitates our subsequent processing of exceptions.
You can also detect other tests by yourself, such as when the offset is 0 or a negative number, and when the data amount is 0 or a negative number. I won’t write more about these. You can first guess what the results will be based on your existing knowledge, and then write your own code to verify that the results are in line with your expectations. The learning effect will be great! (There is a test in the test code link below, and the result is that there are pitfalls)
总结
一个功能使用了三种方式来实现,这就是代码的魅力。至于哪个好哪个坏我们不多做评价,一切都是以业务为核心来进行选取。类似的功能虽说并不常见,但很多项目里都会遇到,比如说后台用户组管理就会非常常见,一般来说后台用户分组如果不是特别大型的 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
推荐学习:《PHP视频教程》