在日常开发的业务环境中,我们一般都会使用 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));
// 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 项目都不会很多,但有时候也会达到需要分页的程度,这时候,我们就可以考虑考虑使用今天所学的知识来做咯!

测试代码:

github.com/zhangyue0503/dev-blog/blob/master/php/202008/source/PHP中的数组分页实现(非数据库).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中的数组分页实现(非数据库)实例讲解的文章就介绍到这了,更多相关PHP中的数组分页实现内容请搜索Devmax以前的文章或继续浏览下面的相关文章希望大家以后多多支持Devmax!

PHP中的数组分页实现(非数据库)实例讲解的更多相关文章

  1. html5使用canvas实现弹幕功能示例

    这篇文章主要介绍了html5使用canvas实现弹幕功能示例的相关资料,需要的朋友可以参考下

  2. 前端实现弹幕效果的方法总结(包含css3和canvas的实现方式)

    这篇文章主要介绍了前端实现弹幕效果的方法总结(包含css3和canvas的实现方式)的相关资料,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  3. H5 canvas实现贪吃蛇小游戏

    本篇文章主要介绍了H5 canvas实现贪吃蛇小游戏,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  4. ios – parse.com用于键,预期字符串的无效类型,但是得到了数组

    我尝试将我的数据保存到parse.com.我已经预先在parse.com上创建了一个名为’SomeClass’的类.它有一个名为’mySpecialColumn’的列,其数据类型为String.这是我尝试使用以下代码保存数据的代码:如果我运行这个我得到:错误:密钥mySpecialColumn的无效类型,预期字符串,但得到数组这就是我在parse.com上的核心外观:有谁知道我为什么会收到这个错误?

  5. ios – 上下文类型’NSFastEnumeration’不能与数组文字一起使用

    斯威夫特3,你会这样做吗?解决方法正如您所发现的,您不能使用as-casting将数组文字的类型指定为NSFastEnumeration.您需要找到一个符合NSFastEnumeration的正确类,在您的情况下它是NSArray.通常写这样的东西:

  6. ios – UIScrollView的平滑自定义分页

    我在UIScrollView中有两个(可能更多)视图,并希望使用分页.当我尝试使用UIScrollView的默认分页选项时出现问题,因为视图具有不同的宽度,无法正确分页.所以我已经实现了一个有效的自定义分页代码.但是,当滚动较慢时,它不会按预期运行.(它回到没有动画的原始位置.)以下是我目前通过uiscrollviewdelegate进行自定义分页的方法我想要的是:是)我有的:解决方法尝试下面的自

  7. ios – 使用子视图控制器分页滚动视图

    使用分页实现水平滚动视图的最佳做法是什么,每页有一个视图控制器?由于iOS5具有用于视图控制器容器/包含的API,因此PageControl示例仍然是实现此功能的最佳方式吗?

  8. ios – 获取资产目录文件夹中所有图像的数组

    在iOS中,是否可以获取资产目录文件夹中的图像数组?我不确定为什么会对此进行投票.我真的不知道从哪里开始.我的另一种方法是创建文件夹中所有文件的plist,但它似乎是多余的.我无法添加任何代码,因为我会添加什么?

  9. ios – 来自调试器的消息:由于内存问题而终止

    我的应用程序使用Geojson文件.我使用MapBoxSDK将MGLpolyline添加到地图中.但问题是我的文件太大,以至于应用程序崩溃并收到错误:来自调试器的消息:由于内存问题而终止.我在第一次循环时面对66234个对象.我试图将数组块化为新数组,但没有成功.请帮我解决问题.这是我在地图上绘制的代码,这里是我的testprojectongithubuseXcode8.1如果有任何不同的第三方可

  10. ios – Swift – 使用字典数组从字典访问数据时出错

    我有一个非常简单的例子,说明我想做什么基本上,我有一个字典,其值包含[String:String]字典数组.我把数据填入其中,但当我去访问数据时,我收到此错误:Cannotsubscriptavalueoftype‘[([String:String])]?’withanindexoftype‘Int’请让我知道我做错了什么.解决方法您的常量数组是可选的.订阅字典总是返回一个可选项.你必须打开它.更

随机推荐

  1. PHP个人网站架设连环讲(一)

    先下一个OmnihttpdProffesinalV2.06,装上就有PHP4beta3可以用了。PHP4给我们带来一个简单的方法,就是使用SESSION(会话)级变量。但是如果不是PHP4又该怎么办?我们可以假设某人在15分钟以内对你的网页的请求都不属于一个新的人次,这样你可以做个计数的过程存在INC里,在每一个页面引用,访客第一次进入时将访问时间送到cookie里。以后每个页面被访问时都检查cookie上次访问时间值。

  2. PHP函数学习之PHP函数点评

    PHP函数使用说明,应用举例,精简点评,希望对您学习php有所帮助

  3. ecshop2.7.3 在php5.4下的各种错误问题处理

    将方法内的函数,分拆为2个部分。这个和gd库没有一点关系,是ecshop程序的问题。会出现这种问题,不外乎就是当前会员的session或者程序对cookie的处理存在漏洞。进过本地测试,includes\modules\integrates\ecshop.php这个整合自身会员的类中没有重写integrate.php中的check_cookie()方法导致,验证cookie时返回的username为空,丢失了登录状态,在ecshop.php中重写了此方法就可以了。把他加到ecshop.php的最后面去就可

  4. NT IIS下用ODBC连接数据库

    $connection=intodbc_connect建立数据库连接,$query_string="查询记录的条件"如:$query_string="select*fromtable"用$cur=intodbc_exec检索数据库,将记录集放入$cur变量中。再用while{$var1=odbc_result;$var2=odbc_result;...}读取odbc_exec()返回的数据集$cur。最后是odbc_close关闭数据库的连接。odbc_result()函数是取当前记录的指定字段值。

  5. PHP使用JpGraph绘制折线图操作示例【附源码下载】

    这篇文章主要介绍了PHP使用JpGraph绘制折线图操作,结合实例形式分析了php使用JpGraph的相关操作技巧与注意事项,并附带源码供读者下载参考,需要的朋友可以参考下

  6. zen_cart实现支付前生成订单的方法

    这篇文章主要介绍了zen_cart实现支付前生成订单的方法,结合实例形式详细分析了zen_cart支付前生成订单的具体步骤与相关实现技巧,需要的朋友可以参考下

  7. Thinkphp5框架实现获取数据库数据到视图的方法

    这篇文章主要介绍了Thinkphp5框架实现获取数据库数据到视图的方法,涉及thinkPHP5数据库配置、读取、模型操作及视图调用相关操作技巧,需要的朋友可以参考下

  8. PHP+jquery+CSS制作头像登录窗(仿QQ登陆)

    本篇文章介绍了PHP结合jQ和CSS制作头像登录窗(仿QQ登陆),实现了类似QQ的登陆界面,很有参考价值,有需要的朋友可以了解一下。

  9. 基于win2003虚拟机中apache服务器的访问

    下面小编就为大家带来一篇基于win2003虚拟机中apache服务器的访问。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  10. Yii2中组件的注册与创建方法

    这篇文章主要介绍了Yii2之组件的注册与创建的实现方法,非常不错,具有参考借鉴价值,需要的朋友可以参考下

返回
顶部