当前位置:

首页 > 编程开发 > ThinkPHP5如何实现分页查询_ThinkPHP5实现分页查询方法【代码】

ThinkPHP5如何实现分页查询_ThinkPHP5实现分页查询方法【代码】

ThinkPHP5使用paginate()分页:必须作为查询链最后方法;参数名不匹配需手动指定;数据量大可跳过COUNT防性能瓶颈;通过items()和render()获取数据与HTML,避免误用。

先聊几句分页这事儿。很多人在ThinkPHP5里做分页,第一步就是去查paginate()的用法,照着文档写个例子,跑起来看着也没毛病。但稍微变个场景——比如URL参数名不一样了、表数据上了百万、或者想自己控制一下分页的行为——就开始出各种奇怪的问题。说到底,分页本身不复杂,真正考验人的,是对这个“黑盒”的理解有多深。

先说最常规的场景。ThinkPHP5里用paginate()做分页,确实是最省事的方式,它自动帮你处理SQL的LIMITOFFSET,还能顺手生成分页的HTML代码。但这里有几个容易被忽略的关键点,一旦没注意,报错信息会非常让人摸不着头脑。

  • paginate()必须是查询链上的最后一个方法。别想着在where()之前就调它,也别跟在find()select()后面再调。严格顺序,否则直接报错。
  • 参数直接传数字,表示每页显示多少条,比如paginate(15)。如果你需要更精细地控制,可以传一个数组,比如paginate(['list_rows'=>20, 'page'=>3])。注意,数组的键名是有规定的,不是随便写。
  • 在调用paginate()之前如果用了field(),记得把主键字段带上(通常是id)。否则,paginate()在统计总数时可能会因为找不到主键而出错。
// 正确写法:先查状态为1的用户,按创建时间倒序,每页10条
$users = User::where('status', 1)
    ->order('create_time DESC')
    ->paginate(10);

// 模板中输出分页HTML,默认是Bootstrap风格
echo $users->render();

手动传入当前页码时,得搞清楚参数名

这是另一个高频坑点。ThinkPHP5默认从$_GET['page']里读当前页码,但现实项目里,带翻页的URL往往是/list?page_no=2或者用了路由变成了/list/p/2。如果没做配置,paginate()始终读到的是null,自然永远显示第一页。

解决办法其实也不复杂,分两种情况:

  • 如果是GET参数名不一样,可以用第三个参数指定:paginate(10, false, ['page' => 'page_no'])。第二个参数false的意思是“不自动获取总记录数”,一般情况下不用动它。
  • 如果用了URL路由(比如list/p/:page),就需要配合input('param.page')手动传页码进去:paginate(10, false, ['page' => input('param.page', 1)])

必须警惕的是,不要在控制器里自己先input('page'),然后把取到的值再传给paginate()。这么做等于绕过了TP5自带的页码校验逻辑,如果传入的是负数或者非数字,SQL就会报异常,这是一个非常隐蔽的坑。

从分页结果对象里取数据,方式和取分页信息要分开

又有新人会踩的雷:$list = User::paginate(10)之后,直接foreach($list as $u),结果报错Invalid argument supplied for foreach()。原因很简单,$list不是一个数组,它是一个Paginator对象。你得用对方法才能拿到里面的东西。

  • 取当前页的数据:用$list->items(),返回的是一个Collection或数组。
  • 取分页的HTML代码:用$list->render(),返回的是字符串。
  • 取总条数:用$list->total()。千万别写成count($list),那个数的是当前页的数据条数,不是总记录数。
  • 模板里输出分页链接时,常见写法是{$data->render|raw},一定要加上|raw,否则HTML会被转义成纯文本,什么都看不到。

数据量大的时候,count()是性能瓶颈

当表里数据到了百万级别,又没有合适的索引时,paginate()默认执行的COUNT(*)可能会耗时好几秒。说到底,这锅真不该让TP5来背,是MySQL本身的查询优化问题。在数据量大到一定程度后,强行优化count()不如换个思路。

  • 直接在paginate()的第二个参数传false来跳过count:paginate(15, false)。这样之后,$list->lastPage()$list->total()是获取不到值的,但hasMore仍然可用——系统会通过判断是否能查到下一页的数据来确定。
  • 前端显示“共 ? 条”的位置,可以留空,或者直接改成“仅显示前N条”。从用户体验角度看,这种诚实反而更友好。
  • 如果确实需要总数,可以单独维护一个缓存里的近似值,比如用定时任务定期更新,没必要每次请求都去执行一次全表COUNT。

最后必须说的是,分页这个功能本身确实不复杂。但真正考验人的,是对paginate()这个“黑盒”的理解:它的count行为、参数解析机制、以及与URL参数的耦合关系,全都藏在think\Paginatorthink\db\Query的源码里。改配置的时候,顺手去翻一下源码里的注释,很多问题其实都能提前避免。

本文内容来源于互联网,如有侵权请联系删除。
作者最新文章
编程开发
相关文章 更多
using namespace 使用中遇到的问题怎么解决
using namespace 使用中遇到的问题怎么解决

命名空间的基本概念与常见引入问题在C++等编程语言中,命名空间(namespace)是一种将代码标识符(如变量、函数、类名)封装在特定名称下的机制,其主要目的是避免命名冲突,尤其是在大型项目或使用多个第三方库时。使用“using namespace”指令可以将指定命名空间中的所有名称引入当前作用域,

c语言函数递归 实操经验总结:这些技巧很实用
c语言函数递归 实操经验总结:这些技巧很实用

理解递归的基本原理在C语言中,递归是一种函数调用自身的编程技术。要掌握它,首先需要理解其核心思想:将一个复杂的大问题,分解为一个或几个与原问题相似但规模更小的子问题,直到子问题足够简单,可以直接求解。这个过程通常包含两个关键部分:递归出口和递归体。递归出口定义了问题何时不再继续分解,即最简单、可直接

c语言函数递归 怎么选?常见方案对比分析
c语言函数递归 怎么选?常见方案对比分析

递归函数的基本概念与适用场景在C语言编程中,递归是一种函数调用自身的编程技巧。它并非适用于所有问题,但在处理某些具有自相似结构的问题时,能提供极其清晰和优雅的解决方案。递归的核心思想是将一个大规模问题分解为一个或多个同类型但规模更小的子问题,直到子问题简单到可以直接求解。典型的适用场景包括树形结构的

Objective-C 内存管理入门:从 alloc 到 dealloc 的生命周期详解
Objective-C 内存管理入门:从 alloc 到 dealloc 的生命周期详解

理解内存管理的基石在Objective-C的编程世界中,内存管理是开发者必须掌握的核心技能之一。它直接关系到应用的性能、稳定性与资源利用效率。与一些采用自动垃圾回收机制的语言不同,Objective-C在很长一段时间里,依赖一套基于引用计数的、需要开发者部分介入的管理规则。这套规则的核心思想是明确的

如何正确使用 dealloc 以避免 iOS 应用中的内存泄漏
如何正确使用 dealloc 以避免 iOS 应用中的内存泄漏

理解 dealloc 的角色与时机在 iOS 应用开发中,内存管理是保障应用性能与稳定性的基石。dealloc 方法是 Objective-C 中对象生命周期结束时的关键回调,它标志着对象即将被系统回收内存。正确理解其触发时机至关重要:当一个对象的引用计数降为零时,运行时系统会自动调用该对象的 de

深入理解 Objective-C 中的 dealloc 方法:内存管理核心机制
深入理解 Objective-C 中的 dealloc 方法:内存管理核心机制

内存管理的基石在Objective-C的世界里,内存管理是开发者必须掌握的核心技能之一。作为一门在手动引用计数(MRC)时代诞生的语言,Objective-C要求程序员对对象的生命周期有清晰的认识。dealloc方法正是这一生命周期中至关重要的终点站。它是一个实例方法,当对象的引用计数降为零时,系统

理解 native2ascii:Java 国际化开发中的字符编码工具
理解 native2ascii:Java 国际化开发中的字符编码工具

native2ascii 工具的基本定位在Ja va应用程序的国际化与本地化开发过程中,处理非拉丁字符集是一个常见且关键的环节。Ja va内部使用Unicode字符集来统一表示全球各种语言的文字,但其属性文件(.properties)在历史上要求使用ASCII编码,或者更准确地说,要求非ASCII字

如何使用 native2ascii 转换中文字符为 Unicode 转义序列
如何使用 native2ascii 转换中文字符为 Unicode 转义序列

理解 native2ascii 工具的基本用途在软件开发,特别是涉及国际化处理的场景中,开发者常常需要处理不同编码的文本资源。native2ascii 是 Ja va 开发工具包(JDK)中提供的一个命令行实用程序,其主要功能是将包含本地字符编码(非ASCII字符)的文件,转换为包含 Unicode

Java native2ascii 命令详解:解决属性文件乱码问题
Java native2ascii 命令详解:解决属性文件乱码问题

native2ascii 命令的由来与作用在Ja va开发中,处理国际化资源文件是一个常见需求。资源文件通常以.properties格式存储,用于支持多语言界面。然而,Ja va属性文件默认采用ISO-8859-1字符集编码,这导致了一个直接的问题:当文件中包含非拉丁字符(如中文、日文、韩文等)时,

一个 memwatch 实战案例:定位野指针问题
一个 memwatch 实战案例:定位野指针问题

内存监控工具的价值与挑战在软件开发,尤其是使用C/C++这类手动管理内存的语言时,内存错误是程序员最常遭遇的难题之一。其中,野指针问题因其隐蔽性和破坏性,往往成为最难定位的“幽灵”缺陷。它可能潜伏在代码中,在特定条件下才被触发,导致程序崩溃、数据损坏或难以预测的行为。传统的调试手段,如打印日志或使用

查看更多
精品专题 更多
装机必备
装机必备

正软商城装机必备专区,精选办公、浏览器、安全防护、影音播放、压缩解压、设计创作和系统工具等电脑常用正版软件,帮助用户快速完成新电脑软件配置。

Windows
Windows

正软商城Windows软件专区,汇集适用于Windows电脑的办公、设计、安全防护、影音播放、开发工具和系统优化软件,提供软件介绍、系统要求、正版授权及购买下载服务。

macOS软件
macOS软件

正软商城macOS软件专区,精选适用于Mac电脑的办公、设计、影音、效率、开发和系统工具,提供软件功能介绍、macOS兼容版本、正版授权及购买下载服务。

Mac软件 更多
灵活计算器
灵活计算器
macOS/iOS/Android

灵活计算器是一款笔记式算数应用,支持实时计算、动态关联和云端同步功能。记录、整理和输出之间的过渡会更自然,适合长期写作、做笔记或持续沉淀个人内容。

赤友清理大师
赤友清理大师
macOS

赤友清理大师是一款为 Mac 设计的智能清理优化工具,可精准扫描垃圾、大文件、重复文件等,释放磁盘空间。做扫描整理、文字提取和表格转换时,它能把识别后的处理步骤接得更顺,资料录入这类场景会省下不少时间。

极度公式
极度公式
Windows/macOS/Linux

极度公式是一款跨平台专业LaTeX公式识别编辑软件,支持OCR公式识别和多平台编辑。和使用说明,避免使用,享受完整功能与稳定支持。做扫描整理、文字提取和表格转换时,它能把识别后的处理步骤接得更顺,资料录入这类场景会省下不少时间。

WINDOWS 更多
Windows 10
Windows 10
Windows

Windows 10 是一款微软推出的经典操作系统,拥有硬件兼容性与多任务处理能力。它更偏向把系统状态查看和常用调节动作放在一起,适合需要持续观察和微调设备状态的场景。

极度公式
极度公式
Windows/macOS/Linux

极度公式是一款跨平台专业LaTeX公式识别编辑软件,支持OCR公式识别和多平台编辑。和使用说明,避免使用,享受完整功能与稳定支持。做扫描整理、文字提取和表格转换时,它能把识别后的处理步骤接得更顺,资料录入这类场景会省下不少时间。

密码键盘
密码键盘
Windows/macOS/iOS/Android

密码键盘是一款兼具安全性与便捷性的高效密码管理器。日常使用里的持续防护和信息管理会更突出,适合把安全控制放进长期使用流程中的场景。