$per_page变量直接控制每页条数,需从来源校验、范围限制和sql拼接三方面确保安全与性能。

PHP分页中 $per_page 变量直接决定每页条数
分页逻辑里真正控制“每页几条”的,通常是一个整型变量(比如 $per_page 或 $limit),它被用于 SQL 的 LIMIT 子句。改它就生效,但要注意来源是否可控、是否校验。
常见写法示例:
$per_page = 10; // ← 改这里即可 $page = isset($_GET['page']) ? (int)$_GET['page'] : 1; $offset = ($page - 1) * $per_page; $sql = "SELECT * FROM articles LIMIT $offset, $per_page";
- 硬编码改值最简单,但不灵活;适合固定需求
- 若从 URL 获取(如
?per_page=20),必须强制转为整型并限制范围,否则易被注入或拖垮数据库 - 推荐加白名单校验:
in_array($per_page, [5, 10, 20, 50]) ? $per_page : 10
用 GET 参数动态传参时,$_GET['per_page'] 必须过滤和兜底
用户能随意改 URL 中的 per_page,比如 ?per_page=999999,不处理会导致查询极慢甚至超内存。不能只靠前端下拉框限制。
- 始终用
(int)强转,再用max(5, min(100, $per_page))限定区间 - 避免直接拼接进 SQL:
"LIMIT $offset, $_GET['per_page']"是危险写法 - 更安全的做法是先校验再赋值:
$per_page = in_array($_GET['per_page'] ?? 10, [5,10,20,50]) ? (int)$_GET['per_page'] : 10; - 注意:如果用了 PDO 预处理,
LIMIT参数不能占位符绑定(MySQL 不支持),仍需手动校验后拼接
配合前端分页控件,URL 里要同步传递 per_page 参数
用户切换每页数量后,翻页链接(上一页、页码、下一页)里的 per_page 值必须保持一致,否则点第二页又变回默认值。
立即学习“PHP免费学习笔记(深入)”;
- 生成页码链接时,把当前
per_page作为查询参数带进去:?page=2&per_page=20 - 不要只保留
page,漏掉per_page就会重置 - 如果用了伪静态(如
/list/2?per_page=20),确保重写规则不丢参数 - 建议封装一个
buildPageUrl($page, $per_page)函数统一处理,避免各处硬写 URL
注意 MySQL 的 LIMIT offset, length 在大数据量下的性能陷阱
当 $page 很大(比如第 10000 页),OFFSET 越大,MySQL 越要扫描前面所有行,即使只取 10 条,也会很慢。
-
$per_page设太大(如 500)不一定好,单页加载慢、内存占用高、用户体验反而差 - 真要支持深分页,得换方案:用游标分页(基于上一页最后 ID)、或用
WHERE id > ? LIMIT 10 - 后台管理可放宽限制,但面向用户的列表建议守住 10–50 条/页这个范围
- 别忘了给
ORDER BY字段建索引,否则LIMIT也救不了性能
实际改的时候,盯着 $per_page 这个变量,查清它从哪来、到哪去、有没有被校验——大部分问题都出在这三步里。











