PHP分页需严格校验$page和$per_page:$page须(int)强转并max(1,$page)兜底;limit应查$per_page+1条试探下一页;URL参数用http_build_query保留搜索条件;$per_page必须(int)转且范围限定,PDO预处理对LIMIT无效。

分页函数怎么传当前页参数才不翻车
PHP 分页函数最常崩在 $page 没校验或类型错——比如 URL 里传来 page=abc,直接当整数用会变成 0,结果查第 0 页,MySQL 报 OFFSET -10 错误(因为 max(1, $page) - 1 算出负偏移)。
必须手动过滤并兜底:
$page = isset($_GET['page']) ? (int)$_GET['page'] : 1;- 再加一层保护:
$page = max(1, $page); - 别信
filter_input(INPUT_GET, 'page', FILTER_SANITIZE_NUMBER_INT),它会把1a2变成12,更危险
limit 和 offset 怎么算才不出界
核心是:总条数未知时,不能只靠 $page * $per_page 做上限判断;否则用户猛点“下一页”,最后一页可能查空还报错。
推荐做法是多查一条试探:
立即学习“PHP免费学习笔记(深入)”;
- 实际查
$per_page + 1条数据 - 如果结果集长度 >
$per_page,说明还有下一页(删掉最后一条再返回) - 这样不用先
COUNT(*),避免双查性能损耗
示例逻辑:$sql = "SELECT * FROM article LIMIT " . ($page - 1) * $per_page . ", " . ($per_page + 1);
生成分页 HTML 时 URL 参数怎么保留
用户带搜索条件进分页,比如 /list.php?cat=php&page=2,翻页后却丢了 cat=php——根本原因是硬写死链接,没解析原始 $_SERVER['QUERY_STRING']。
安全提取方式:
- 用
http_build_query(array_merge($_GET, ['page' => $new_page]))拼新 URL - 务必先
unset($params['page'])再 merge,否则 page 参数叠成page=3&page=5 - 别直接正则替换
page=\d+,URL 编码、特殊字符、参数顺序都容易漏
为什么用 PDO 预处理也得防 SQL 注入
分页参数本身不进 SQL 字符串,但很多人把 $per_page 直接拼进 LIMIT 子句,比如:"LIMIT " . $per_page。这时候如果 $per_page = "10, 100",就变成 LIMIT 10, 100 → 实际查 100 条,但更糟的是被注入成 LIMIT 10; DROP TABLE user--(虽然 MySQL 不支持多语句,但风险意识不能松)。
正确姿势:
-
$per_page和$offset必须转(int),且限定范围(如min(100, max(1, (int)$per_page))) - PDO 的
bindValue对LIMIT无效(不是占位符位置),只能靠强转+范围限制 - 别图省事用
mysqli_real_escape_string处理数字参数——它对数字无效,纯属心理安慰
边界永远比想象中薄,$page 和 $per_page 这两个变量,一个少校验,一个少截断,分页就从工具变成漏洞入口。











