应校验页码合法性:删数据后重新统计总数,计算最大合法页码,若请求页码超出则重定向至最后一页或首页,并严格过滤page参数为正整数。

删除数据后总页数变少,但当前页码还存在怎么办
删掉一批记录后,原第 5 页可能已不存在——比如总共只剩 12 条数据(每页 10 条),实际只有 2 页,但用户仍停留在 ?page=5。此时直接查第 5 页会返回空结果,页面显示空白,体验断裂。
核心思路是:**在分页查询前,先校验请求的 page 是否超出合法范围**。不是靠前端禁用按钮,而是服务端兜底。
- 先用
COUNT(*)获取删除后的总记录数(注意:必须在 delete 后重新统计,不能复用旧缓存) - 计算最大合法页码:
$maxPage = (int)ceil($total / $perPage) - 若
$_GET['page'] > $maxPage && $maxPage > 0,重定向到$maxPage;若$maxPage === 0,说明没数据了,可跳首页或提示“暂无内容”
DELETE 操作和分页逻辑不在同一事务里,导致页码错乱
常见错误是:先执行 DELETE FROM table WHERE id IN (...),再查 COUNT(*) 分页,中间没加事务或没强制刷新查询缓存。尤其在高并发下,其他请求可能同时插入/删除,导致刚算出的总页数立刻失效。
更稳妥的做法是把「删」和「算总数」放在同一查询上下文中,避免中间状态干扰:
立即学习“PHP免费学习笔记(深入)”;
- 使用
SELECT SQL_CALC_FOUND_ROWS(MySQL 8.0.17+ 已弃用,慎用)不如直接两次查询清晰 - 推荐:删完立即执行
SELECT COUNT(*) FROM table WHERE ...(带相同条件),确保统计口径一致 - 如果用了 Redis 缓存总数量,删除后必须同步
DEL对应 key,不能只靠过期时间
前端传参 page=0 或负数,后端没过滤引发越界或 SQL 报错
page 参数不是可信输入。PHP 默认不会自动转整型,$_GET['page'] 可能是字符串 "abc"、"0"、"-1",直接参与计算会导致 OFFSET 为负或非数字,PDO 报 SQLSTATE[HY000]: General error,或 MySQL 返回空结果。
必须显式过滤并归一化:
- 用
(int)$_GET['page']强转后,再判断是否,强制设为 1 - 或用
filter_input(INPUT_GET, 'page', FILTER_VALIDATE_INT, ['options' => ['default' => 1, 'min_range' => 1]]) - 注意:不要用
abs(),因为page=-999变成999依然越界
Laravel/Eloquent 中 delete() 后 paginate() 仍显示旧页码
Eloquent 的 paginate() 是链式调用,它内部会自己执行 COUNT 和 LIMIT/OFFSET 查询。但如果先调 Model::whereIn('id', $ids)->delete(),再调 Model::paginate(10),两者完全独立——paginate() 不知道你刚删过什么。
关键点在于:**删除和分页必须共用同一查询构造器实例,或确保删除后重新构建完整查询**:
- 错误写法:
User::whereIn('id', $ids)->delete(); User::paginate(10);(两次独立查询) - 正确写法:删完后用全新查询
User::query()->paginate(10),或封装成方法统一处理总数逻辑 - 如果用了
withCount()或全局作用域,确认删除操作没绕过这些逻辑(例如直接 DB::delete() 就不会触发模型事件)
最易被忽略的是:分页跳转链接里的 page 参数,往往由前端拼接或 JS 生成,删完数据后没同步更新分页控件的 data-total-pages 或禁用按钮,用户点“下一页”时仍发旧参数。服务端校验是底线,但前后端配合才能真正消除空白页。











