ThinkPHP 3.2 实现带 Where 条件的分页查询
在 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 进阶技巧的资料请关注本站其它相关文章!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









