php翻页函数应只负责分页逻辑,权限过滤须在调用前通过预处理where条件完成;paginate()必须支持参数绑定、校验$page/$limit为正整数,严禁字符串拼接sql。

PHP翻页函数如何自动过滤非本角色可见的数据
直接在分页逻辑里混入角色判断,等于把权限控制和数据分页耦合在一起,后续改权限规则就得动翻页函数——这是最常踩的坑。正确做法是让分页函数只管「取哪几条」,而「能取哪些」由上游查询条件决定。
比如管理员能看到全部订单,普通用户只能看到自己的,那 WHERE 条件就该在调用分页前拼好:
$baseQuery = "SELECT * FROM orders";
$params = [];
if ($userRole === 'user') {
$baseQuery .= " WHERE user_id = ?";
$params[] = $userId;
}
// 分页函数只接收已过滤的查询骨架
$paginated = paginate($baseQuery, $params, $page, $limit);
paginate() 函数必须支持预绑定参数,否则 SQL 注入风险极高
很多手写的翻页函数直接拼接 $page 和 $limit 进 SQL,但忽略前面的 WHERE 条件也可能带用户输入。只要用了 $_GET 或用户可控字段做条件,就必须走预处理。
关键点:
-
paginate()内部不能用字符串拼接构造完整 SQL,只能用?占位符 +array_merge($whereParams, [$offset, $limit]) - 必须校验
$page和$limit为正整数,intval($page) 就强制设为 1 - 数据库层若用 MySQL,
LIMIT参数顺序是LIMIT offset, size,别写反
count() 查询也得复用同一套 WHERE 条件,否则总页数算错
分页要显示「共 XX 页」,就得执行一次 COUNT(*)。如果这个 COUNT 没带上角色过滤条件,管理员看的是 1000 条,用户点进去却只有 23 条,页码栏还显示 50 页——点击第 2 页直接空结果。
实操建议:
- 把基础查询语句(不含
SELECT字段和LIMIT)抽成变量,如$countQuery = str_replace('SELECT *', 'SELECT COUNT(*)', $baseQuery) - 确保
$countQuery和分页主查询用完全相同的$params,连顺序都不能差 - 别为了省一次查询,在前端硬算总页数(
ceil($totalCount / $limit)),后端不校验会导致越界请求返回空数组
分页链接生成时,role 和 user_id 不能暴露在 URL 上
有人为了让不同角色看到不同分页,把 ?role=admin&uid=123 挂在链接里,这等于把权限开关明文交给前端——用户改个参数就能越权查看。
安全做法是:
- 分页链接只保留
?page=2这类无状态参数 - 角色和用户身份从 session 或 JWT 中读取,每次请求都重新校验
- 如果真需要跨角色跳转(如管理员临时切换视角),应走独立入口并记录审计日志,不走通用分页链路
角色隔离不是给分页加 if-else,而是让每条分页请求背后,都运行着一条「已经过权限剪裁」的 SQL。漏掉 WHERE、漏掉 count 同步、漏掉参数绑定,任何一个点都会让隔离失效。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











