直接改paginate配置即可切换分页类,无需修改框架源码;需继承think\Paginator并重写render()和getLinks()方法,通过配置'type'=>'自定义类名'注册,确保命名空间与目录结构匹配。

直接改 paginate 配置就能换分页类,不用动框架源码
ThinkPHP 5.1+ 和 TP6 默认用的是 Bootstrap 分页驱动,但它的 HTML 结构和 class 名是固定的(比如 .pagination、.page-link)。想彻底控制输出,最稳妥的方式不是改 vendor 里的文件,而是自定义一个分页类并注册进去。
关键点在于:配置项 'type' 支持类名或完整命名空间,TP 会自动实例化它。你只需要保证类继承 think\Paginator 或其子类,并实现 render() 方法即可。
- 自定义类必须放在
app\paginator\driver\目录下(推荐),或确保能被自动加载 - 类名要与文件名一致,命名空间需匹配目录结构,例如
app\paginator\driver\Simple - 配置中写
'type' => 'Simple'即可生效,TP 会自动拼接命名空间 - 别在
vendor里直接改Bootstrap.php—— Composer 更新后会被覆盖
setConfig() 只能改文字和主题模板,不能改 HTML 标签结构
很多人以为调用 $list->setConfig('prev', '上一页') 就能深度定制样式,其实它只影响字符串内容和 %UP_PAGE% 这类占位符的替换逻辑,底层仍走默认的 Bootstrap::render() 流程。如果你需要:
- 把
<ul><li></ul>换成<div class="pager"> <li>去掉 <code>aria-label或data-page属性 - 让“当前页”不包裹在
<a></a>里,而是用<span class="current"></span>
那 setConfig() 完全无能为力 —— 它不碰 DOM 结构,只负责填充文字。
立即学习“PHP免费学习笔记(深入)”;
真正起作用的是你自定义类里的 render() 方法。例如:
public function render()
{
$html = '<div class="pager">';
$html .= $this->home() . $this->prev();
foreach ($this->getLinks() as $link) {
$html .= $link;
}
$html .= $this->next() . $this->last();
$html .= '</div>';
return $html;
}TP6 中自定义分页类必须重写 getLinks() 才能控制页码范围
TP6 的 Bootstrap 驱动内部用 $this->getUrlRange() 生成页码数组,但这个方法是 protected 的,外部不可见。你继承它之后,如果只是覆盖 render(),页码逻辑还是原样跑。
所以真正要干预“显示哪几个数字页”,得重写 getLinks() 方法。常见需求如:
- 始终显示首页和尾页:
$block['first'] = $this->getUrlRange(1, $this->lastPage); - 只显示当前页前后各 2 个页码:
$start = max(1, $this->currentPage() - 2); $end = min($this->lastPage, $this->currentPage() + 2); - 隐藏首页/尾页按钮当页数少于 5 页时:加
if ($this->lastPage 判断
注意:TP6 的 $this->currentPage() 返回的是 int,而 TP5 是 string,类型差异会影响比较逻辑。
CSS 样式无法覆盖时,优先检查 class 是否被 render() 输出
很多开发者写了 .pagination .current { color: red; } 却没效果,根本原因往往是:你用的自定义分页类压根没输出 class="current" —— 它可能输出的是 class="active" 或 class="on",甚至什么 class 都没加。
解决步骤很简单:
- 先在模板里输出
{$list->render()|htmlspecialchars},看原始 HTML 是什么结构 - 确认 class 名是否和你的 CSS 选择器完全一致(区分大小写、空格、连字符)
- 如果用了
theme配置,注意它只对内置Bootstrap类生效,自定义类不识别该参数 - 避免用
!important硬顶 —— 应该让 class 名对齐,而不是靠权重覆盖
最易忽略的一点:TP6 默认开启「简洁模式」(simple = true)时,render() 只输出上/下一页链接,不输出任何页码数字 —— 此时 .current 根本不会出现。



















