thinkphp的paginate()默认只识别page和list_rows两个get参数,其他如p、size等会被忽略;需显式传参或全局配置config/paginate.php,且路由参数须手动提取,appends()不支持嵌套键名,应改用withquery()。

分页参数传不进 paginate() 是因为只认 page 和 list_rows
ThinkPHP 默认只从 $_GET 里提取 page 和 list_rows 这两个键,其他如 p、size、offset 全部忽略。你发 /?p=2&size=20,它照样返回第 1 页、默认条数。
解决方法有两个:
- 控制器调用时显式传参:
$list->paginate(15, false, ['page' => input('p/d', 1), 'list_rows' => input('size/d', 15)]) - 全局配置(TP6.1+):在
config/paginate.php中写'page' => 'p', 'list_rows' => 'size'
注意:路由路径里的参数(如 /list/2)不会被自动识别,必须手动提取后传给 paginate()。
appends() 追加复杂参数失败,本质是不支持嵌套键名
像 filter[status]=1 或 sort[by]=name&sort[dir]=desc 这类带中括号的参数,直接 $list->appends($_GET) 会出问题——appends() 内部用 http_build_query() 拼接,但没做键名扁平化,结果生成 ?page=2&filter=[status]=1,后端收不到 filter['status']。
正确做法是先 flatten 再过滤:
- 跳过分页相关键(
page、list_rows等) - 把
filter[status]展开成filter_status或保留原格式但确保 URL 编码合规 - 推荐用 TP6+ 的
withQuery()替代appends(),它原生支持嵌套数组解析
别图省事直接传 $_GET,这是最常踩的坑。
URL 参数含下划线或空格,不是分页逻辑错,是 Web 服务器提前动了手脚
现象是 $_GET['order_by'] 变成 order%5Fby 或直接丢失,这不是 paginate() 的锅。先看原始请求串:var_dump($_SERVER['QUERY_STRING']),再对比 var_dump($_GET) —— 若二者不一致,问题出在 Nginx/Apache 或 CGI 层。
常见诱因:
- Nginx 的
merge_slashes off或错误rewrite规则导致下划线被转义 - Apache 的
AllowEncodedSlashes配置异常 - 框架中间件或路由层对
$_GET做了二次urldecode()
安全拼链接时,每个参数值必须用 rawurlencode($value),不能用 urlencode()(它把空格转 +,易错乱);整个 query string 别再套一次编码,否则 & 和 = 会被毁掉。
分页模板替换后样式不生效,大概率是模板路径没对上主题名
ThinkPHP 分页渲染优先级是:view/[theme_name]/paginate.html → 框架内置模板 → 驱动类 render() 方法。你改了 think\paginator\driver\Bootstrap 类,但页面没变,说明根本没加载到你的模板。
检查点:
- 当前是否设置了模板主题?没设就是默认主题,模板路径应为
view/paginate.html - 如果用了主题(比如
theme' => 'admin'),那你的模板必须放在view/admin/paginate.html - 模板里必须有
{$page->render()}或等效输出,否则连基础结构都不渲染 - TP6.3+ 推荐用
$list->render(['template' => 'common/paginate'])动态指定,比放固定路径更可控
最容易忽略的是主题名和目录名不一致,多一个空格、大小写不对、路径少一级,都会 fallback 到框架默认模板。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











