ThinkPHP6分页需手动处理参数保留、动态页大小及模板适配。用appends()追加查询参数,input('size/d')获取每页条数并禁用自动page解析,复制paginate.tpl到应用层修改结构,或继承Paginator封装自定义分页类。

ThinkPHP6.x 的分页不是单纯调用一个方法就完事,关键在于参数传递不丢失和样式能贴合前端结构。默认 render() 输出的 HTML 往往和你用的 Bootstrap、LayUI 或自定义 CSS 不匹配,而 URL 参数(比如搜索关键词、分类 ID)一翻页就清空,这是最常踩的两个坑。
保留查询参数,避免翻页丢条件
用户在带搜索框或筛选项的列表页翻页时,必须把当前所有有效参数带上。ThinkPHP6 不会自动继承 GET 参数,得手动处理:
- 用
appends()追加参数:在控制器中获取并追加,例如$list = User::where('status', 1)->appends(['keyword' => input('keyword'), 'cate' => input('cate')])->paginate(15) - 如果参数多,可直接传入整个请求参数:
appends(request()->except('page')),排除 page 防止冲突 - 注意:不要在 paginate() 的配置数组里再写
'query',和 appends() 混用会导致重复拼接
控制每页条数支持动态切换
用户想自己选“每页显示 10 条 / 20 条 / 50 条”,不能只靠固定数字。ThinkPHP6 默认不从 URL 自动读取 size 参数,需手动提取:
- 先取值:
$size = input('size/d', 15);(/d 表示整型过滤,防注入) - 再分页:
User::paginate($size, false, ['page' => input('page/d', 1)]),第二个参数false很关键——关掉自动解析 URL 中的 page,避免 page 被解析两次导致错乱 - 视图中提供下拉选择,并确保链接 href 包含
&size=20等参数
替换默认分页模板,适配前端框架
直接改 vendor 里的模板不推荐,升级会覆盖。稳妥做法是复制模板到应用层再修改:
立即学习“PHP免费学习笔记(深入)”;
- 复制
vendor/topthink/framework/src/view/paginate.tpl到app/view/common/paginate.tpl - 在配置文件
config/paginate.php中设置:'template' => 'common/paginate.tpl' - 按需重写 HTML 结构,比如 Bootstrap 用
<ul class="pagination">,LayUI 用<div class="layui-box">,里面用{$first}、{$prev}、{$pages}、{$next}、{$last}等变量控制逻辑
进阶:自定义分页类(适合统一管理样式)
当多个模块都要用同一套分页 HTML 和 JS 行为(比如点击页码不跳转、用 AJAX 加载),建议封装分页类:
- 新建
app/common/paginator/BootstrapPage.php,继承think\Paginator - 重写
render()方法,返回符合 Bootstrap 5 语义的<nav><ul class="pagination">...</ul></nav> - 在
app/provider.php中注册:think\Paginator::macro('bootstrap', function () { return new \app\common\paginator\BootstrapPage(...); }); - 视图中调用:
{$list|raw}或自定义函数输出



















