php中pdo分页核心是用limit ? offset ?配合类型校验与范围限制,通过独立count(*)查询获取总记录数,再封装为可复用方法,注意防止sql注入、越界及大偏移量性能问题。

PHP 中使用 PDO 实现分页查询,核心是结合 SQL 的 LIMIT 和 OFFSET(或 MySQL 8.0+ 的 OFFSET ... FETCH),配合 PHP 计算当前页码、每页条数、总记录数等参数,动态生成查询语句并安全执行。
基础分页 SQL 与 PDO 绑定
MySQL 常用分页语法为:LIMIT ? OFFSET ?,其中两个问号分别对应“每页数量”和“起始偏移量”。PDO 支持位置占位符绑定,需确保传入整型值:
- 偏移量 = (当前页码 − 1) × 每页条数(页码从 1 开始)
- 必须对页码、每页数做类型校验和范围限制,防止 SQL 注入或越界
- 示例代码片段:
$page = max(1, (int)$_GET['page'] ?? 1); $perPage = max(1, min(100, (int)$_GET['limit'] ?? 10)); // 限制最多 100 条/页 $offset = ($page - 1) * $perPage; <p>$sql = "SELECT id, title, created_at FROM articles ORDER BY id DESC LIMIT ? OFFSET ?"; $stmt = $pdo->prepare($sql); $stmt->execute([$perPage, $offset]); $items = $stmt->fetchAll(PDO::FETCH_ASSOC);
获取总记录数(用于计算页码总数)
分页需要知道总条数才能渲染页码导航。推荐用独立的 COUNT(*) 查询(不带 LIMIT),与主查询复用相同 WHERE 条件:
在现实生活中的购物过程,购物者需要先到商场,找到指定的产品柜台下,查看产品实体以及标价信息,如果产品合适,就将该产品放到购物车中,到收款处付款结算。电子商务网站通过虚拟网页的形式在计算机上摸拟了整个过程,首先电子商务设计人员将产品信息分类显示在网页上,用户查看网页上的产品信息,当用户看到了中意的产品后,可以将该产品添加到购物车,最后使用网上支付工具进行结算,而货物将由公司通过快递等方式发送给购物者
- 避免在主查询中用
SQL_CALC_FOUND_ROWS(已弃用且性能差) - WHERE 条件需完全一致,建议提取为变量或函数统一管理
- 例如有搜索条件:
WHERE status = ? AND title LIKE ?,COUNT 查询也应包含相同条件
$countSql = "SELECT COUNT(*) FROM articles WHERE status = ?"; $countStmt = $pdo->prepare($countSql); $countStmt->execute([1]); $total = (int)$countStmt->fetchColumn();
封装成可复用的分页方法
将分页逻辑抽象为函数或类方法,提高复用性与可维护性:
立即学习“PHP免费学习笔记(深入)”;
- 接收 PDO 实例、基础 SQL(不含 LIMIT/OFFSET)、WHERE 参数数组、页码、每页数
- 内部自动拼接 COUNT 查询 + 分页主查询,返回含
items、total、page、per_page、last_page的数组 - 对非法页码自动纠正(如超出范围则返回最后一页)
注意边界与安全性
实际使用中容易忽略的关键点:
- 页码为 0 或负数时,默认按第 1 页处理;超过最大页数时,返回空结果或跳转到最后一页
- 不要直接拼接用户输入到 SQL(如用
"LIMIT ".$_GET['limit']),必须走预处理绑定 - 大偏移量(如
OFFSET 100000)会导致性能下降,数据量大时建议改用“游标分页”(基于上一页最后 ID)










