直接用range()生成页码会导致页面卡顿、UI溢出和SEO差,应采用三段式构造:起始固定段(1、2)、中间动态段(当前页±2)、结尾固定段(倒数两页),空隙处插入省略号。

为什么直接用 range() 生成页码会出问题
因为 range(1, $total_pages) 在总页数多时(比如 200 页),会把所有数字塞进导航栏,页面卡顿、UI 溢出、SEO 友好性也差。真实场景里用户根本不会点到第 187 页——他们只关心「当前页前后各 2 页 + 首尾 + 省略号」。
核心逻辑:三段式构造页码数组
真正可靠的翻页导航不是“渲染所有页”,而是拼出三个区块:起始固定段(1、2)、中间动态段(当前页 ±2)、结尾固定段(倒数两页)。省略号只在段与段之间有空隙时才插入。
关键判断条件:
- 如果
$current_page≤ 4,起始段取[1, 2, 3],中间段从4开始,结尾段保留[$total_pages - 1, $total_pages] - 如果
$current_page≥$total_pages - 3,结尾段取最后三个,起始段固定为[1, 2],中间段前移 - 否则中间段是
[$current_page - 2, $current_page - 1, $current_page, $current_page + 1, $current_page + 2]
每段之间检查是否需要加 ...:比如起始段最大值是 3,中间段最小值是 5 → 中间缺 4,就插一个 ...;同理中间段最大值是 9,结尾段最小值是 12 → 缺 10 和 11,也插 ...。
PHP 实现示例(无框架依赖)
// $total_pages = 100; $current_page = 42;
function buildPagination($total_pages, $current_page) {
$pages = [];
<pre class="brush:php;toolbar:false;">// 起始段
$pages[] = 1;
if ($total_pages > 1) $pages[] = 2;
// 中间段:±2,但要防越界
$start = max(3, $current_page - 2);
$end = min($total_pages - 1, $current_page + 2);
for ($i = $start; $i 1) $pages[] = $total_pages;
// 插入省略号(只在缺口大于 1 时)
$final = [];
foreach ($pages as $i => $p) {
if ($i === 0 || $p === 1 || $p === $total_pages) {
$final[] = $p;
continue;
}
$prev = $final[count($final)-1];
if ($p - $prev > 1) $final[] = '...';
$final[] = $p;
}
return $final;}
这个函数返回的是纯数字 + 字符串 ... 的数组,后续用 foreach 渲染即可。注意它不处理 URL 参数拼接,实际使用时需手动补上 ?page= 或路由参数。
容易被忽略的边界坑
很多实现栽在这些地方:
-
$current_page超出范围($total_pages)没校验,导致range()报 Warning 或空数组 - 省略号插错位置:比如
[1, 2, ..., 5, 6]是对的,但写成[1, 2, ..., ..., 5, 6]就重复了 - 没过滤重复页码:当
$current_page是 2 或 3 时,起始段和中间段可能重叠,不array_unique()或提前判断会渲染出2, 2, 3 - 前端没给
...加禁用样式,用户点它会触发page=...请求,后端没兜底就 500
最麻烦的其实是移动端小屏下的换行和点击热区——省略号得用 … 而不是三个英文点,并且包裹在 <a></a> 里时必须加 pointer-events: none 或服务端跳过链接渲染。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











