必须将排序和分页下推至数据库,用 ORDER BY + LIMIT/OFFSET 实现;PHP 数组排序后切片仅适用于几百条内的静态小数据,否则内存与性能崩溃。

PHP 排序后分页不能先 array_sort 再切片,否则内存和性能会崩——尤其是数据量稍大(比如上千条)时。必须把排序逻辑下推到数据库,用 SQL 的 ORDER BY + LIMIT/OFFSET 一次性完成,否则 PHP 数组分页只是玩具级方案。
数据库排序 + LIMIT/OFFSET 是唯一靠谱路径
绝大多数真实场景(列表页、后台管理、API 返回)的数据源是 MySQL/PostgreSQL,排序和分页必须由数据库承担:
- PHP 对数组做
usort或array_multisort后再array_slice,等于把全量数据拉到 PHP 内存里,排序完再丢弃 99% —— 白耗内存、拖慢响应、无法加索引加速 - 数据库的
ORDER BY field能走索引,LIMIT能终止扫描;而 PHP 排序是全量比较,没优化余地 - 即使你用
array_chunk分页,也得先有完整数组;它只适合小数据(
正确姿势:SQL 中写明排序字段和方向,再拼分页参数。
PHP 怎么安全传参给 LIMIT 和 OFFSET
直接拼字符串进 SQL 是严重漏洞,$_GET['page'] 可被注入成 1; DROP TABLE users;。必须绑定整型参数:
- 用
(int)强转页码,并用max(1, ...)防负值:$page = max(1, (int)($_GET['page'] ?? 1)); -
$per_page必须白名单控制(如固定 10/20/50),不能从用户输入读取 - 预处理语句中,
LIMIT和OFFSET必须用PDO::PARAM_INT绑定,不能当字符串插进去
示例:
$offset = ($page - 1) * $per_page;
$stmt = $pdo->prepare("SELECT id, title, created_at FROM posts ORDER BY created_at DESC LIMIT :limit OFFSET :offset");
$stmt->bindValue(':limit', $per_page, PDO::PARAM_INT);
$stmt->bindValue(':offset', $offset, PDO::PARAM_INT);
$stmt->execute();
数组内部分页只适用于极小数据或调试
真要对 PHP 数组排序后分页(比如配置项、枚举列表、缓存下来的静态数据),流程是:
- 先用
usort或array_multisort排好序(注意回调函数返回 -1/0/1,别用==) - 用
array_slice($sorted, $offset, $per_page)截取,不是array_chunk—— 后者生成二维数组,多一层嵌套且浪费内存 - 总页数仍用
ceil(count($sorted) / $per_page)算,但必须确保$sorted不超几百项
错误示范(常见坑):
// ❌ 错:$data 是关联数组,array_chunk 后 $paged[0] 是子数组,不是你要的那页数据 $paged = array_chunk($data, $per_page, true); $current = $paged[$page - 1] ?? []; <p>// ✅ 对:直接 slice,返回一维子数组 $offset = ($page - 1) * $per_page; $current = array_slice($data, $offset, $per_page, true); </p>
真正难的不是写对那几行代码,而是判断「该不该在 PHP 层做排序分页」——只要数据来自数据库,就别动这个念头。索引、执行计划、连接池、查询缓存,这些底层优势,PHP 数组一个都用不上。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











