thinkphp 的 paginate() 不自动生成首页、尾页和跳转框,需手动拼接html并严格校验:首页/尾页须独立判断禁用状态,$other_params 应用 http_build_query 合并参数,跳转框须前后端双重校验,且 render() 前禁止调用 toarray() 等序列化操作。

ThinkPHP 的 paginate() 本身不生成首页、尾页和跳转框,这些必须手动拼接 HTML 并配合逻辑控制;直接依赖 render() 默认输出会漏掉关键入口,且无法响应跳转输入。
首页/尾页链接不能塞进页码循环里
很多人把首页写成 for ($i = $start; $i 循环中的一个分支(比如 <code>if ($i == 1)),这会导致两个问题:一是首页语义丢失,变成“第一页的别名”;二是当前页为 1 时,首页仍参与高亮判断,容易被误禁用。
- 首页链接应独立写出:
@#@#@#@#@#@#@#@#@#@0,禁用逻辑只看if ($list->currentPage() == 1) - 尾页同理:
@#@#@#@#@#@#@#@#@#@1,禁用条件是if ($list->currentPage() == $list->lastPage()) -
$other_params推荐用http_build_query(array_merge(request()->param(), ['page' => '']))构建,确保 keyword、sort 等参数透传且 page 被清空
跳转框需要前后端协同校验
前端放个 <input type="number"> 不代表后端就能安全跳转——没做校验的跳转等于开放 SQL 注入温床(虽然不直接操作 SQL,但可能触发异常查询或资源耗尽)。
- PHP 端必须接收并清洗:
$jump = input('jump/d', 0),/d过滤器保证是整数,再加if ($jump $list->lastPage())拦截越界 - 跳转必须用
header('Location: ' . url('', array_merge(request()->param(), ['page' => $jump]))); exit;,不能拼字符串,否则路由参数丢失 - 模板中跳转框要带当前页参数:
<input type="number" name="jump" value="" min="1" max="<?php echo $list->lastPage(); ?>">,避免用户输超范围值还提交
render() 前调用 toArray() 或 json() 会让分页失效
这是 ThinkPHP 分页最隐蔽的坑:一旦你对分页对象做了 toArray()、json() 或 return $list(API 场景),$list->render() 就彻底不可用——它依赖未序列化的对象状态来生成 URL 和元信息。
- 正确 API 返回结构应为:
['data' => $list->items(), 'total' => $list->total(), 'per_page' => $list->listRows(), 'current_page' => $list->currentPage(), 'last_page' => $list->lastPage()] - 如果非要自定义 HTML 渲染(比如加首页/尾页),就别调
render(),改用$list->simple()获取精简对象,再手写<a></a>标签 - 模板里用
{$list->render()}前,确认控制器没对$list做任何转换操作;哪怕只是foreach ($list as $v) { }后再 render,某些版本也会静默失败
首页和尾页不是“可有可无的装饰”,它们是用户快速逃离深页码的逃生通道;跳转框也不是炫技功能,而是对搜索结果页、后台列表等场景的真实需求。真正难的不是写出链接,而是在 query 参数动态变化、每页条数可调、URL 风格自定义的前提下,让所有链接始终指向正确上下文——这要求你放弃“套个方法就完事”的思路,从 paginate() 的参数穿透开始,一层层核对 URL 生成逻辑。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











