正确使用thinkphp 6.0 paginate()需从查询构造器链式调用,显式传入page参数,模板中用{$list->render()}输出分页条,通过appends()保留搜索条件,可自定义模板或继承paginator类彻底控制渲染逻辑。

刚写完用户列表查询,发现数据一多页面就卡顿、翻页没反应、页码显示错乱——这不是代码写错了,是没用对ThinkPHP 6.0的paginate()方法,更没处理好分页参数透传和模板渲染路径。
控制器里正确调用paginate获取分页数据
必须从查询构造器开始链式调用,不能在select()之后补paginate()。否则会报Call to undefined method think\Collection::paginate()错误。
使用模型时:UserModel::where('status', 1)->paginate(15);使用Db门面时:Db::name('user')->where('status', 1)->paginate(10)。
【page参数不会自动从URL读取,必须显式传入配置】 如果你的URL是?pagenum=2&size=20,就得手动提取:$page = input('pagenum/d', 1); $size = input('size/d', 15); UserModel::paginate($size, ['page' => $page])。
漏掉第二个参数数组里的'page' => $page,框架仍会去找默认的page参数,导致翻页始终停在第1页。
模板中安全输出分页HTML
在视图里直接写{$list->render()}即可输出Bootstrap风格分页条,但前提是$list是Paginator实例,不是数组或Collection。
别用count($list)获取总条数——它返回的是当前页数据量;要用{$list->total()}显示“共 X 条”,用{$list->lastPage()}获取末页页码。
如果项目没引入Bootstrap,直接输出会丢失CSS样式,但HTML结构仍可被自定义CSS选中,比如.pagination .page-link。
保留搜索条件等非page参数
方法一:用appends()追加当前请求中除page外的所有参数:{$list->appends(request()->except(['page']))->render()}。
方法二:只保留特定字段,避免空值污染URL:{$list->appends(request()->only(['keyword', 'category', 'status']))->render()}。
注意:request()->only()只取GET参数,POST参数不会混入分页链接,比input()更安全。
快速自定义分页HTML结构(不改类)
第一步:找到框架默认模板位置,通常是vendor/topthink/think-orm/src/paginator/driver/bootstrap4.php。
第二步:把它复制到resources/view/paginate/simple.php(路径可自定,但需保证可读)。
第三步:在控制器分页调用后,显式指定模板:$list->render('simple'),注意不带.php扩展名。
第四步:打开simple.php,删掉所有aria-label属性,把<ul class="pagination"></ul>换成<div class="pager">,保存即可生效。
<p>模板内可用变量有$paginator、$currentPage、$lastPage、$hasPrevious、$hasNext,但不要用已弃用的$render。</p>
<h2>注册并启用自定义分页类(彻底控制渲染逻辑)</h2>
<p>方法一:创建类文件<code>app/paginator/driver/MyPager.php,内容包含命名空间app\paginator\driver、类名MyPager,继承think\paginator\driver\Bootstrap。
方法二:重写render()方法,在里面拼接跳转输入框HTML,并用$this->url('$PAGE$')生成跳转链接,占位符必须是$PAGE$而非[PAGE]。
方法三:关键一步——重写getLinks(),否则页码范围仍是默认的±2。例如强制显示全部页码:return $this->getUrlRange(1, $this->lastPage);。
最后在分页调用时设'type' => 'MyPager',TP6会自动加载该类,无需修改任何配置文件或provider绑定。











