thinkphp 5.1+ 自定义分页参数名需继承原分页驱动类并重写 getcurrentpage() 方法,同时配置 var_page 控制链接参数名,二者缺一不可;仅改 var_page 或手动修改 $_get 均无效。

ThinkPHP 5.1+ 如何自定义分页的 page 参数名
默认情况下,ThinkPHP 的分页组件(Paginator)只认 page 这个 URL 参数来获取当前页码。如果你的前端或接口规范要求用 pn、current 或其他名称,直接改 URL 不起作用——分页器压根不读它。
根本原因是:分页器初始化时会调用 input('page')(或 input('page/d', 1)),这个行为写死在 think\paginator\driver\Bootstrap 等驱动类的构造逻辑里,但框架留了钩子让你覆盖。
- 最稳妥的方式是创建自定义分页器类,继承原驱动并重写
getCurrentPage()方法 - 不要试图用
$_GET手动赋值再传给paginate(),因为paginate()内部仍会重新调用input()读取 - ThinkPHP 6.0+ 的
LengthAwarePaginator同样适用该方案,只是命名空间不同
重写 getCurrentPage() 获取自定义参数
以 ThinkPHP 5.1 为例,在 app\common\paginator\CustomBootstrap.php 中定义:
namespace app\common\paginator;
use think\paginator\driver\Bootstrap;
class CustomBootstrap extends Bootstrap
{
protected function getCurrentPage()
{
// 改成读取 'pn' 参数,fallback 到 1
$page = input('pn/d', 1);
return $this->app->validate($page, 'number>=1') ? (int) $page : 1;
}
}
然后在控制器中显式使用它:
$list = Db::name('user')->paginate(10, false, [
'type' => 'app\common\paginator\CustomBootstrap',
'var_page' => 'pn', // 这个影响生成的分页链接里的参数名
]);
-
var_page控制分页 HTML 链接中显示的参数名(如?pn=2),但它不影响读取逻辑——读取由getCurrentPage()决定 - 必须同时改
getCurrentPage()和var_page,否则会出现“点下一页跳转的是pn=2,但服务端仍按page=2解析”的错位 - 如果用了
simple()分页,也要确保自定义类继承自SimpleBootstrap并重写对应方法
全局替换所有分页的参数名(不推荐但可行)
如果你项目里所有分页都要统一改成 current,可以在应用初始化(如 app\common\behavior\InitHook.php)中重绑定分页驱动:
// 注意:此方式侵入性强,升级 ThinkPHP 时需反复核对
Container::get('think\Paginator')
->setDriver('bootstrap', function ($app) {
return new \app\common\paginator\CustomBootstrap($app);
});
更轻量的做法是封装一个助手函数:
function custom_paginate($list, $per_page = 15, $config = [])
{
$default = [
'type' => 'app\common\paginator\CustomBootstrap',
'var_page' => 'current',
];
return $list->paginate($per_page, false, array_merge($default, $config));
}
- 这种封装能避免到处写重复配置,也方便后续统一调整
- 别在
config/pagination.php里硬改'var_page',它只控制默认驱动的输出参数名,不改变读取逻辑
为什么不能只改 var_page 或只改 input() 调用?
常见错误是只设置 'var_page' => 'p',结果点击分页链接后数据没变——因为 Paginator 构造时仍执行 input('page'),而 URL 里根本没有 page 参数,返回默认值 1。
另一个典型错误是在控制器开头手动 $_GET['page'] = $_GET['p'] ?? 1,这看似“欺骗”了 input(),但 ThinkPHP 的 input() 函数底层缓存了原始请求数据,运行时修改 $_GET 无效。
- ThinkPHP 的请求输入是快照式的,不是实时读取
$_GET - 分页器读取页码发生在
paginate()执行的早期阶段,此时你还没机会干预 - 唯一可靠路径就是接管
getCurrentPage(),这是框架明确开放的扩展点
真正要改参数名,就老老实实重写那个方法。其他绕路操作,99% 会掉进缓存或时机陷阱里。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











