ThinkPHP 3.2 实现带 Where 条件的分页查询

沿途有光
沿途有光
发布时间:2026-10-14| 2人浏览过
原创

在 PHP 开发中,经常需要根据特定条件(如当前登录用户)筛选数据并进行分页展示。本文将详细解析如何在 ThinkPHP 框架中,利用 Model 的 count 方法和 Page 类,结合 array 类型的 where 条件,实现精准的分页查询功能。

实现原理与目标

本实例的核心目标是:在获取数据列表时,既应用特定的过滤条件(例如仅显示当前登录用户的数据),又保证分页导航栏中的“总共X页”和“第Y条/共Z条”计算准确。这需要先执行一次计数查询统计满足条件的总行数,再执行第二次查询获取当前页的具体数据。

准备工作

环境要求: ThinkPHP 3.x 版本(使用内置 ORG.Util.Page 类库)。如果使用 TP5/TP6,建议改用原生 paginate 方法,语法更简洁。 前置逻辑: 确保用户已登录,且 $_SESSION['loginUserId'] 中存在有效的用户 ID。

具体操作步骤

第1步:引入分页类库并初始化模型

目的: 加载框架提供的分页处理工具,并实例化需要操作的数据表模型。

操作: 使用 D('Announcement') 实例化公告模型,并通过 import() 函数引入核心分页类。

$Form = D('Announcement');
import("ORG.Util.Page");

第2步:统计符合条件数据总数

目的: 为分页器提供总数据量,这是生成分页导航的关键参数。

操作: 对模型调用 count() 方法。注意:如果后续查询有条件限制,此处也应保持一致性或先查总数再查详情(本例中因无复杂关联,直接 count 所有或需结合条件计数,但在该简单示例中,原代码直接使用了全表计数或默认条件,实际生产环境中若需严格对应,应在 count 中也传入同样的 map)。

// 计算符合条件的数据总数
// 注意:严谨写法应传入相同的 $map,即 $Form->where($map)->count()
$count = $Form->count(); 

第3步:实例化分页对象

目的: 定义每页显示的行数和总行数,内部将自动计算总页数。

操作: 创建 Page 对象,第一个参数为总数 $count,第二个参数为每页显示条数(例如 5 条)。

// 每页显示5条数据
$p = new Page($count, 5);

第4步:构建 Where 查询条件

目的: 指定数据过滤规则,确保只返回当前登录用户的相关记录。

操作: 创建一个关联数组(Map),键名为数据库字段名,值为期望匹配的值。可以混合使用 Session 变量、POST 提交值等。

$map = array();
// 从会话中获取当前用户ID,并设置为查询条件
$map['user_id'] = $_SESSION['loginUserId'];

// 其他条件可继续添加,例如状态筛选
// $map['status'] = 1;

第5步:执行查询并获取结果集

目的: 根据分页器生成的 SQL 片段(limit)和之前定义的查询条件,拉取当前页的数据。

操作: 链式调用 Model 的方法:where() 应用条件,order() 指定排序(如按ID降序),limit() 应用分页范围,最后使用 findAll() 获取二维数组结果。

$list = $Form
    ->limit($p->firstRow . ',' . $p->listRows)
    ->order('announcement_id desc')
    ->where($map)
    ->findAll();

// 调试时可取消注释查看最终生成的 SQL 语句
// dump($Form->getLastSql()); 

第6步:渲染分页导航

目的: 生成 HTML 格式的分页链接(上一页、下一页、页码跳转等),以便在前端展示。

操作: 调用分页对象的 show() 方法,将结果赋值给变量供视图层输出。

$page = $p->show();

关键代码整合

以下是完整的 Controller 核心逻辑代码,可直接参考:

$Form = D('Announcement');
import("ORG.Util.Page");

// 1. 构建条件
$map['user_id'] = $_SESSION['loginUserId'];

// 2. 统计总数 (建议传入相同条件以确保准确性)
$count = $Form->where($map)->count();

// 3. 初始化分页
$p = new Page($count, 5);

// 4. 查询数据
$list = $Form
    ->limit($p->firstRow . ',' . $p->listRows)
    ->order('announcement_id desc')
    ->where($map)
    ->findAll();

// 5. 获取分页HTML
$page = $p->show();

// 6. 分配模板变量
$this->assign('list', $list);
$this->assign('page', $page);
$this->display();

排错与注意事项

  • 总数偏差问题: 原代码示例中直接使用了 $Form->count() 而未传参,若数据库中有其他用户数据,会导致分页总数偏大。请务必在 count() 中也加入 where($map),保证计数与查询条件一致。
  • SQL 注入安全: 虽然 ThinkPHP 的数组方式查询能自动处理转义,但请确保 $_SESSION 中的数据是可信的内部数据。如果是前端传入的参数,建议使用框架提供的过滤机制或白名单验证。
  • 版本差异: 上述代码基于 ThinkPHP 3.2 标准。如果你使用的是更高版本(如 TP5+),推荐直接使用 $Form->where($map)->paginate(5),系统会自动处理计数和 SQL 生成,代码量可减少至三行以内。

简要总结

通过手动实例化 Page 类并配合 Model 的链式操作,可以灵活地实现复杂的条件分页查询。关键在于确保 count() 统计的数量与后续查询使用的 where 条件保持完全一致,以避免出现空页或数据断层。以上就是 ThinkPHP 有变量的 where 条件分页实例的详细解读,更多关于 ThinkPHP 进阶技巧的资料请关注本站其它相关文章!

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。