当前位置: 首页 > 后端技术 > PHP

PHP中的数组分页实现(非数据库)

时间:2023-03-29 23:02:48 PHP

在日常开发的业务环境中,我们一般使用MySQL语句来实现分页功能。但是往往数据不多,或者获取一些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作为第一页。这个我就不多解释了,相信大家只要正式学习过或者参与过开发项目就会明白它的意思。然后我们定义当前页面显示的信息条数$pageSize,即只获取3条数据。最后我们计算出偏移量,这个和MySQL的LIMIT中的参数类似。它的作用是告诉我们从哪一项开始查询,然后配合$pageSize查询多少项。这样我们就可以获取到当前页面对应的数据了。(好像已经解释了分页的原理)array_slice的第一个也是最基本也是最常用的分页方法是使用array_slice()函数来实现的。它的作用是从数组中截取一段内容,返回一个包含这段内容的数组。var_dump(array_slice($data,$offset,$pageSize));//数组(3){//[0]=>//字符串(1)"D"//[1]=>//字符串(1)"E"//[2]=>//string(1)"F"//}array_slice()函数需要三个参数,第二个参数是偏移量,第三个参数是查询几条数据.其中,第三个参数可选,不填则显示当前设置的offset之后的所有数据。是不是和我们的MySQL查询语句一模一样?没错,它们本身就是类似的操作。array_chunkkarray_chunk()函数根据一个数值参数对数组进行分组,即将数组一个一个地划分为子数组。然后我们可以根据拆分后的数组获取指定下标的子数组内容,也就是当前页面需要展示的数据。$pages=array_chunk($data,$pageSize);var_dump($pages);//array(4){//[0]=>//array(3){//[0]=>//string(1)"A"//[1]=>//字符串(1)"B"//[2]=>//字符串(1)"C"//}//[1]=>//数组(3){//[0]=>//字符串(1)"D"//[1]=>//字符串(1)"E"//[2]=>//字符串(1)"F"//}//[2]=>//数组(3){//[0]=>//字符串(1)"G"//[1]=>//字符串(1)"H"//[2]=>//字符串(1)"I"//}//[3]=>//数组(2){//[0]=>//字符串(1)"J"//[1]=>//字符串(1)"K"//}//}var_dump($pages[$currentPage]);//数组(3){//[0]=>//字符串(1)"A"//[1]=>//string(1)"B"//[2]=>//string(1)"C"//}这段代码我们输出分割数组的内容,然后第二页就是下标为1的数据,直接通过分数组就可以轻松得到需要的内容。使用这个函数做数组分页非常简单直观,不需要计算偏移量。可以直接使用当前页的$currentPage和$pageSize来完成数据的分组。强烈建议您使用此功能来做类似的事情。我们需要学习的关于LimitIterator的最后一件事是使用迭代器类来实现数组分页的能力。这个很少用到,估计也没人知道,但其实在PHP5.1中已经提供了LimitIterator类。它所做的是允许遍历迭代器的限定子集的元素。也就是说,如果我们的代码使用了迭代器模式,实现了迭代器接口,那么这些迭代器类就可以使用这个类来进行分页操作。foreach(newLimitIterator(newArrayIterator($data),$offset,$pageSize)as$d){var_dump($d);}//string(1)"D"//string(1)"E"//string(1)"F"需要3个实例化构造参数,第一个是迭代器对象,由于数组不是迭代器对象,所以我们使用ArrayIterator实例将我们的数组数据转化为迭代器对象。最后两个参数是偏移量和数据量。这类似于array_slice()函数,不同的是它的offset参数也是可选的。如果我们不给后面的可选参数,那么它会遍历所有的数据。foreach(newLimitIterator(newArrayIterator($data))as$d){var_dump($d);}//string(1)"A"//string(1)"B"//string(1)"C"//字符串(1)"D"//字符串(1)"E"//字符串(1)"F"//字符串(1)"G"//字符串(1)"H"//字符串(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]=>//字符串(1)"F"//[3]=>//字符串(1)"G"//[4]=>//字符串(1)"H"//[5]=>//字符串(1)"I"//[6]=>//字符串(1)"J"//[7]=>//字符串(1)"K"//}var_dump(array_slice($data,15,$pageSize));//array(0){//}array_slice()函数对偏移量错误的兼容性是显示一个空数组。如果数据量超过限制,将显示偏移量之后的所有数据。var_dump($pages[15]);//NULLarray_chunk()当然对于下标不存在的数据返回NULL值。foreach(newLimitIterator(newArrayIterator($data),$offset,150)as$d){var_dump($d);}//字符串(1)"D"//字符串(1)"E"//字符串(1)"F"//字符串(1)"G"//字符串(1)"H"//字符串(1)"I"//字符串(1)"J"//字符串(1)"K"foreach(newLimitIterator(newArrayIterator($data),15,$pageSize)as$d){var_dump($d);}//Fatalerror:UncaughtOutOfBoundsException:Seekposition15isoutofrangeLimitIteratorisforoffset如果数据量不对,直接返回错误异常信息。这也是类模式处理的好处。任何错误都会以异常的形式返回,方便我们对异常进行后续处理。其他测试也可以自己查,比如offset为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.phphttps://www.php.net/manual/zh/function.array-chunk.phphttps://www.php.net/limititerator各媒体平台均可搜索【硬核项目经理】